function callHelper(args, useCurrentContext) { // Validate and parse the args var name = args && Base.getValue(args[0]), result = new Base.UnknownType(), isModule, eventDescription; if (!name) { name = new Base.UndefinedType(); } if (Base.type(name) === "Unknown") { eventDescription = "A value that could not be evaluated was passed to require"; Runtime.fireEvent("requireUnresolved", eventDescription, { name: "<Could not evaluate require path>" }); Runtime.reportWarning("requireUnresolved", eventDescription, { name: "<Could not evaluate require path>" }); return result; } name = Base.toString(name).value; // We don't process plugins or urls at compile time if (pluginRegExp.test(name) || name.indexOf(":") !== -1) { Runtime.fireEvent("requireUnresolved", "Plugins and URLS can not be evaluated at compile-time and will be deferred to runtime.", { name: name }); } else { // Resolve the path isModule = name[0] !== "/" && !name.match(fileRegExp); name = path.resolve(path.join(path.dirname(name[0] !== "." ? Runtime.fileStack[0] : Runtime.getCurrentFile()), name)); name += isModule ? ".js" : ""; // Make sure that the file exists and then process it if (fs.existsSync(name)) { Runtime.fireEvent("requireResolved", "The require path '" + name + "' was resolved", { name: name }); result = CodeProcessor.processFile(name, isModule, useCurrentContext)[1]; } else { eventDescription = "The require path '" + name + "' was resolved"; Runtime.fireEvent("requireMissing", eventDescription, { name: name }); Runtime.reportError("requireMissing", eventDescription, { name: name }); } } return result; }
Runtime.on('tiPropertyReferenced', function (e) { var name = e.data.name, location = e.filename + ':' + e.line + ':' + e.column, deprecatedAPIInfo; if (e.data.node.deprecated) { // TODO: Change deprecated message when we have the 'deprecated since' info from jsca Runtime.reportWarning('deprecatedTiPropertyReferenced', '"' + name + '" has been deprecated', { property: name }); deprecatedAPIInfo = results.deprecatedAPIs[name]; if (deprecatedAPIInfo) { deprecatedAPIInfo.numInstances++; if (deprecatedAPIInfo.locations.hasOwnProperty(location)) { deprecatedAPIInfo.locations[location]++; } else { deprecatedAPIInfo.locations[location] = 1; } } else { results.deprecatedAPIs[name] = { numInstances: 1, locations: {} }; results.deprecatedAPIs[name].locations[location] = 1; } } });
Runtime.on('tiPropertyReferenced', function(e) { var platformList = e.data.node.userAgents, i = 0, len = platformList.length, isSupported = false, name = e.data.name; for(; i < len; i++) { if (platform === platformList[i].platform) { isSupported = true; } } if (!isSupported) { Runtime.reportWarning('invalidPlatformReferenced', 'Property "' + name + '" is not supported on ' + platform, { property: name, platform: platform }); if (results.invalidAPIs[name]) { results.invalidAPIs[name] += 1; } else { results.invalidAPIs[name] = 1; } } });
files.forEach(function (file) { file = Base.toString(file); if (Base.type(file) !== 'String') { eventDescription = 'A value that could not be evaluated was passed to Ti.include'; Runtime.fireEvent('tiIncludeUnresolved', eventDescription, { name: '<Could not evaluate Ti.include path>' }); Runtime.reportWarning('tiIncludeUnresolved', eventDescription, { name: '<Could not evaluate Ti.include path>' }); return result; } file = file.value; if (file[0] === '.') { filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().file), file)); } else { filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), platform, file)); if (!fs.existsSync(filePath)) { filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), file)); } } // Make sure the file exists if (fs.existsSync(filePath)) { Runtime.fireEvent('tiIncludeResolved', 'The Ti.include path "' + filePath + '" was resolved', { file: filePath }); // Fire the parsing begin event Runtime.fireEvent('fileProcessingBegin', 'Processing is beginning for file "' + filePath + '"', { file: filePath }); // Eval the code evalFunc = Runtime.getGlobalObject().get('eval'); evalFunc.call(thisVal, [new Base.StringType(fs.readFileSync(filePath).toString())], false, filePath); // Fire the parsing end event Runtime.fireEvent('fileProcessingEnd', 'Processing finished for file "' + filePath + '"', { file: filePath }); } else { eventDescription = 'The Ti.include path "' + filePath + '" could not be found'; Runtime.fireEvent('tiIncludeMissing', eventDescription, { name: filePath }); Runtime.reportError('tiIncludeMissing', eventDescription, { name: filePath }); } });
callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) { var name = Base.toString(args[0]); if (Base.type(name) != 'Unknown') { name = name.value; if (tiappProperties.hasOwnProperty(name)) { delete tiappProperties[name]; Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name + '" specified Tiapp.xml was removed, the value of this property cannot be guaranteed'); } } return new Base.UndefinedType(); })
files.forEach(function (filename) { filename = Base.toString(filename); if (Base.type(filename) !== 'String') { eventDescription = 'A value that could not be evaluated was passed to Ti.include'; Runtime.fireEvent('tiIncludeUnresolved', eventDescription); Runtime.reportWarning('tiIncludeUnresolved', eventDescription); return result; } filename = filename.value; if (filename[0] === '.') { filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().filename), filename)); } else { filePath = path.resolve(path.join(Runtime.sourceInformation.sourceDir, options.platform, filename)); if (!existsSync(filePath)) { filePath = path.resolve(path.join(Runtime.sourceInformation.sourceDir, filename)); } } // Make sure the file exists if (existsSync(filePath)) { Runtime.fireEvent('tiIncludeResolved', 'The Ti.include path "' + filePath + '" was resolved', { name: filename, path: filePath }); // Fire the parsing begin event Runtime.fireEvent('enteredFile', 'Processing is beginning for file "' + filePath + '"', { filename: filePath }); // Eval the code evalFunc = Base.getGlobalObject().get('eval'); evalFunc.callFunction(thisVal, [new Base.StringType(fs.readFileSync(filePath).toString())], true, filePath); this._location = { filename: filePath, line: 1, column: 1 }; } else { eventDescription = 'The Ti.include path "' + filename + '" could not be found'; Runtime.fireEvent('tiIncludeMissing', eventDescription, { name: filename }); Runtime.reportError('tiIncludeMissing', eventDescription); } }.bind(this));
Runtime.on('tiPropertyReferenced', function(e) { var platformList = e.data.node.userAgents, location = e.filename + ':' + e.line + ':' + e.column, i, len, isSupported = false, name = e.data.name, invalidAPI; for (i = 0, len = platformList.length; i < len; i++) { if (platform === platformList[i].platform) { isSupported = true; } } if (!isSupported) { Runtime.reportWarning('invalidPlatformReferenced', 'Property "' + name + '" is not supported on ' + platform, { property: name, platform: platform }); invalidAPI = results.invalidAPIs[name]; if (invalidAPI) { invalidAPI.numInstances++; if (invalidAPI.locations.hasOwnProperty(location)) { invalidAPI.locations[location]++; } else { invalidAPI.locations[location] = 1; } } else { results.invalidAPIs[name] = { numInstances: 1, locations: {} }; results.invalidAPIs[name].locations[location] = 1; } } });
exports.getOverrides = function (options) { if (options.globalsOnly) { return []; } var tiappProperties = options.tiappProperties, setProperty = Base.wrapNativeCall(function setProperty(thisVal, args) { var name = Base.toString(args[0]); if (Base.type(name) != 'Unknown') { name = name.value; if (tiappProperties.hasOwnProperty(name)) { delete tiappProperties[name]; Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name + '" specified Tiapp.xml was overwritten, the value of this property cannot be guaranteed'); } } return new Base.UndefinedType(); }), p; function createGetFunction(type) { return Base.wrapNativeCall(function getProperty(thisVal, args) { var name = Base.toString(args[0]); if (Base.type(name) == 'Unknown') { return new Base.UnknownType(); } name = name.value; if (!tiappProperties[name]) { return new Base.UnknownType(); } else if (tiappProperties[name].type != type) { return new Base.UndefinedType(); } else { return tiappProperties[name]; } }); } for (p in tiappProperties) { switch(tiappProperties[p].type) { case 'string': tiappProperties[p].value = new Base.StringType(tiappProperties[p].value); break; case 'bool': tiappProperties[p].value = new Base.BooleanType(tiappProperties[p].value); break; case 'int': case 'double': tiappProperties[p].value = new Base.NumberType(tiappProperties[p].value); break; default: Runtime.reportWarning('invalidTiappPropertyType', 'Invalid tiapp.xml property type "' + tiappProperties[p].type + '"'); delete tiappProperties[p]; } } return [{ regex: /^Titanium\.App\.getBool$/, callFunction: createGetFunction('bool') },{ regex: /^Titanium\.App\.getDouble$/, callFunction: createGetFunction('double') },{ regex: /^Titanium\.App\.getInt$/, callFunction: createGetFunction('int') },{ regex: /^Titanium\.App\.getString$/, callFunction: createGetFunction('string') },{ regex: /^Titanium\.App\.hasProperty$/, callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) { var name = Base.toString(args[0]); if (Base.type(name) == 'Unknown') { return new Base.UnknownType(); } name = name.value; return tiappProperties[name] ? new Base.BooleanType(true) : new Base.UnknownType(); }) },{ regex: /^Titanium\.App\.removeProperty$/, callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) { var name = Base.toString(args[0]); if (Base.type(name) != 'Unknown') { name = name.value; if (tiappProperties.hasOwnProperty(name)) { delete tiappProperties[name]; Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name + '" specified Tiapp.xml was removed, the value of this property cannot be guaranteed'); } } return new Base.UndefinedType(); }) },{ regex: /^Titanium\.App\.setBool$/, callFunction: setProperty },{ regex: /^Titanium\.App\.setDouble$/, callFunction: setProperty },{ regex: /^Titanium\.App\.setInt$/, callFunction: setProperty },{ regex: /^Titanium\.App\.setString$/, callFunction: setProperty }]; };
RequireFunction.prototype.call = function call(thisVal, args) { // Validate and parse the args var name = args && Base.getValue(args[0]), filePath, result = new Base.UnknownType(), isModule, eventDescription; if (!name) { name = new Base.UndefinedType(); } name = Base.toString(name); if (Base.type(name) !== 'String') { eventDescription = 'A value that could not be evaluated was passed to require'; Runtime.fireEvent('requireUnresolved', eventDescription); Runtime.reportWarning('requireUnresolved', eventDescription); return result; } name = name.value; if (pluginRegExp.test(name) || name.indexOf(':') !== -1) { Runtime.fireEvent('requireUnresolved', 'Plugins and URLS can not be evaluated at compile-time and will be deferred until runtime.', { name: name }); } else { // Determine if this is a Titanium module if (modules.commonjs && modules.commonjs && modules.commonjs.hasOwnProperty(name)) { isModule = true; filePath = modules.commonjs[name]; } else if (modules[platform] && modules[platform] && modules[platform].hasOwnProperty(name)) { isModule = true; } if (isModule) { if (filePath) { if (cache[filePath]) { Runtime.fireEvent('requireResolved', 'The require path "' + filePath + '" was resolved', { name: filePath }); result = cache[filePath]; } else { result = processFile(filePath, true)[1]; cache[filePath] = result; } } else { Runtime.fireEvent('requireSkipped', 'Native modules cannot be evaluated at compile-time and will be deferred until runtime', { name: name }); } } else { // Resolve the path isModule = !name.match(fileRegExp); // I kinda hate this, but there are too many incorrect usages of require in the wild to implement the spec correctly if (name[0] === '.') { filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().filename), name)); filePath += isModule ? '.js' : ''; } else { filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), platform, name)); filePath += isModule ? '.js' : ''; if (!existsSync(filePath)) { filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), name)); filePath += isModule ? '.js' : ''; } } // Make sure that the file exists and then process it if (existsSync(filePath)) { if (cache[filePath]) { result = cache[filePath]; } else { Runtime.fireEvent('requireResolved', 'The require path "' + filePath + '" was resolved', { name: filePath }); result = processFile(filePath, isModule)[1]; cache[filePath] = result; } } else { eventDescription = 'The require path "' + filePath + '" could not be found'; Runtime.fireEvent('requireMissing', eventDescription, { name: filePath }); Runtime.reportError('requireMissing', eventDescription, { name: filePath }); } } } return result; };