mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-30 23:43:37 +00:00
Merge remote-tracking branch 'cappuccino/master' into plainsliderfix
This commit is contained in:
@@ -66,6 +66,10 @@ if (typeof OBJJ_COMPILER_FLAGS !== 'undefined')
|
||||
case "InlineMsgSend":
|
||||
flags.inlineMsgSendFunctions = true;
|
||||
break;
|
||||
|
||||
case "SourceMap":
|
||||
flags.sourceMap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
FileExecutable.setCurrentCompilerFlags(flags);
|
||||
@@ -180,4 +184,4 @@ GLOBAL(objj_import) = function()
|
||||
{
|
||||
CPLog.warn("objj_import is deprecated, use objj_importFile instead");
|
||||
objj_importFile.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -914,4 +914,4 @@ GLOBAL(CFCopyLocalizedStringWithDefaultValue) = function (key, tableName, bundle
|
||||
GLOBAL(CFBundleGetMainBundle) = function ()
|
||||
{
|
||||
return CFBundle.mainBundle();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -366,42 +366,6 @@ function FileRequest(/*CFURL*/ aURL, onsuccess, onfailure, onprogress)
|
||||
if (aURL.pathExtension() === "plist")
|
||||
request.overrideMimeType("text/xml");
|
||||
|
||||
#if COMMONJS
|
||||
if (aURL.pathExtension().toLowerCase() === "j")
|
||||
{
|
||||
var aFilePath = aURL.toString().substring(5),
|
||||
OS = require("os"),
|
||||
gccFlags = require("objective-j").FileExecutable.currentGccCompilerFlags(),
|
||||
chunk,
|
||||
fileContents = "";
|
||||
|
||||
try
|
||||
{
|
||||
var gcc = OS.popen("gcc -E -x c -P " + (gccFlags ? gccFlags : "") + " " + OS.enquote(aFilePath), { charset:"UTF-8" });
|
||||
while (chunk = gcc.stdout.read())
|
||||
fileContents += chunk;
|
||||
}
|
||||
finally
|
||||
{
|
||||
gcc.stdin.close();
|
||||
gcc.stdout.close();
|
||||
gcc.stderr.close();
|
||||
}
|
||||
|
||||
if (fileContents.length > 0)
|
||||
{
|
||||
request._nativeRequest.responseText = fileContents;
|
||||
onsuccess({request: request});
|
||||
}
|
||||
else
|
||||
{
|
||||
onfailure({request: request});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
var loaded = 0,
|
||||
progressHandler = null;
|
||||
|
||||
|
||||
@@ -597,7 +597,7 @@ CFPropertyList.propertyListFromXML = function(/*String | XMLNode*/ aStringOrXMLN
|
||||
object = decodeHTMLComponent(FIRST_CHILD(XMLNode) ? TEXT_CONTENT(XMLNode) : "");
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case PLIST_DATE: var timestamp = Date.parseISO8601(TEXT_CONTENT(XMLNode));
|
||||
object = isNaN(timestamp) ? new Date() : new Date(timestamp);
|
||||
break;
|
||||
@@ -667,4 +667,4 @@ GLOBAL(CPPropertyListCreateFromData) = function(/*CFData*/ data, /*Format*/ aFor
|
||||
GLOBAL(CPPropertyListCreateData) = function(/*PropertyList*/ aPropertyList, /*Format*/ aFormat)
|
||||
{
|
||||
return CFPropertyList.dataFromPropertyList(aPropertyList, aFormat);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -91,7 +91,7 @@ exports.run = function(args)
|
||||
|
||||
if (argv[0] === "--help" || argv[0] === "-h")
|
||||
{
|
||||
print("Usage (objj): " + args[0] + " [options] [--] files...");
|
||||
print("Usage (objj): " + args[0].split("/").pop() + " [options] [--] files...");
|
||||
print(" -v, --version print the current version of objj");
|
||||
print(" -I, --objj-include-paths include a specific framework paths")
|
||||
print(" -h, --help print this help");
|
||||
@@ -150,6 +150,35 @@ exports.run = function(args)
|
||||
flags.inlineMsgSendFunctions = true;
|
||||
ObjectiveJ.FileExecutable.setCurrentCompilerFlags(flags);
|
||||
break;
|
||||
|
||||
case "-g":
|
||||
case "--include-debug-symbols":
|
||||
argv.shift();
|
||||
var flags = ObjectiveJ.FileExecutable.currentCompilerFlags();
|
||||
flags.includeMethodFunctionNames = true;
|
||||
ObjectiveJ.FileExecutable.setCurrentCompilerFlags(flags);
|
||||
break;
|
||||
|
||||
case "-T":
|
||||
case "--dont-include-type-signatures":
|
||||
argv.shift();
|
||||
var flags = ObjectiveJ.FileExecutable.currentCompilerFlags();
|
||||
flags.includeIvarTypeSignatures = true;
|
||||
flags.includeMethodArgumentTypeSignatures = true;
|
||||
ObjectiveJ.FileExecutable.setCurrentCompilerFlags(flags);
|
||||
break;
|
||||
|
||||
case "-O2":
|
||||
case "--inline-msg-send":
|
||||
argv.shift();
|
||||
var flags = ObjectiveJ.FileExecutable.currentCompilerFlags();
|
||||
flags.inlineMsgSendFunctions = true;
|
||||
ObjectiveJ.FileExecutable.setCurrentCompilerFlags(flags);
|
||||
break;
|
||||
|
||||
default:
|
||||
print(args[0].split("/").pop() + " illegal option " + argv[0]);
|
||||
OS.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,22 +2,21 @@
|
||||
function ObjectiveJLoader() {
|
||||
var loader = {};
|
||||
var factories = {};
|
||||
|
||||
|
||||
loader.reload = function(topId, path) {
|
||||
if (!global.ObjectiveJ)
|
||||
if (!global.ObjectiveJ)
|
||||
global.ObjectiveJ = require("objective-j");
|
||||
|
||||
//print("loading objective-j: " + topId + " (" + path + ")");
|
||||
|
||||
factories[topId] = ObjectiveJ.make_narwhal_factory(path);
|
||||
factories[topId].path = path;
|
||||
}
|
||||
|
||||
|
||||
loader.load = function(topId, path) {
|
||||
if (!factories.hasOwnProperty(topId))
|
||||
loader.reload(topId, path);
|
||||
return factories[topId];
|
||||
}
|
||||
|
||||
|
||||
return loader;
|
||||
};
|
||||
|
||||
|
||||
@@ -275,4 +275,4 @@ GLOBAL(objj_debug_typecheck) = function(expectedType, object)
|
||||
actualType = typeof object;
|
||||
|
||||
throw ("expected=" + expectedType + ", actual=" + actualType);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -81,4 +81,4 @@ EventDispatcher.prototype.dispatchEvent = function(/*Event*/ anEvent)
|
||||
|
||||
if (manual)
|
||||
manual(anEvent);
|
||||
}
|
||||
};
|
||||
|
||||
+167
-10
@@ -21,9 +21,10 @@
|
||||
*/
|
||||
|
||||
|
||||
var ExecutableUnloadedFileDependencies = 0,
|
||||
ExecutableLoadingFileDependencies = 1,
|
||||
ExecutableLoadedFileDependencies = 2,
|
||||
var ExecutableUnloadedFileDependencies = 0,
|
||||
ExecutableLoadingFileDependencies = 1,
|
||||
ExecutableLoadedFileDependencies = 2,
|
||||
ExecutableCantStartLoadYetFileDependencies = 3,
|
||||
AnonymousExecutableCount = 0;
|
||||
|
||||
function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String*/ aURL, /*Function*/ aFunction, /*ObjJCompiler*/aCompiler, /*Dictionary*/ aFilenameTranslateDictionary)
|
||||
@@ -40,13 +41,21 @@ function Executable(/*String*/ aCode, /*Array*/ fileDependencies, /*CFURL|String
|
||||
this._fileDependencies = fileDependencies;
|
||||
this._filenameTranslateDictionary = aFilenameTranslateDictionary;
|
||||
|
||||
if (fileDependencies.length)
|
||||
// This is a little hacky but if fileDependencies is null we can start loading file dependencies yet
|
||||
if (!fileDependencies)
|
||||
{
|
||||
this._fileDependencyStatus = ExecutableCantStartLoadYetFileDependencies;
|
||||
this._fileDependencyCallbacks = [];
|
||||
}
|
||||
else if (fileDependencies.length)
|
||||
{
|
||||
this._fileDependencyStatus = ExecutableUnloadedFileDependencies;
|
||||
this._fileDependencyCallbacks = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
this._fileDependencyStatus = ExecutableLoadedFileDependencies;
|
||||
}
|
||||
|
||||
if (this._function)
|
||||
return;
|
||||
@@ -168,7 +177,7 @@ Executable.prototype.execute = function()
|
||||
}
|
||||
this._compiler.popImport();
|
||||
|
||||
this.setCode(this._compiler.compilePass2());
|
||||
this.setCode(this._compiler.compilePass2(), this._compiler.map());
|
||||
|
||||
if (FileExecutable.printWarningsAndErrors(this._compiler, exports.messageOutputFormatInXML))
|
||||
throw "Compilation error";
|
||||
@@ -197,7 +206,7 @@ Executable.prototype.code = function()
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.code);
|
||||
|
||||
Executable.prototype.setCode = function(code)
|
||||
Executable.prototype.setCode = function(code, sourceMap)
|
||||
{
|
||||
this._code = code;
|
||||
|
||||
@@ -219,7 +228,24 @@ Executable.prototype.setCode = function(code)
|
||||
//if (YES) {
|
||||
var absoluteString = this.URL().absoluteString();
|
||||
|
||||
code += "/**/\n//# sourceURL=" + absoluteString;
|
||||
code += "/**/\n//# sourceURL=" + absoluteString + "s";
|
||||
if (sourceMap)
|
||||
{
|
||||
// The new Function constructor will add a function header before the first line
|
||||
// The compiler adds a new line as the first character to the code to get the spurce
|
||||
// mapping correct. We have to remove it here
|
||||
code = code.substring(2);
|
||||
|
||||
var sourceMapBase64;
|
||||
|
||||
if (typeof btoa === 'function')
|
||||
sourceMapBase64 = btoa(UTF16ToUTF8(sourceMap));
|
||||
else if (typeof Buffer === 'function')
|
||||
sourceMapBase64 = new Buffer(sourceMap).toString("base64");
|
||||
|
||||
if (sourceMapBase64)
|
||||
code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + sourceMapBase64;
|
||||
}
|
||||
//} else {
|
||||
// // Firebug only does it for "eval()", not "new Function()". Ugh. Slower.
|
||||
// var functionText = "(function(){"+GET_CODE(aFragment)+"/**/\n})\n//# sourceURL="+GET_FILE(aFragment).path;
|
||||
@@ -244,6 +270,13 @@ Executable.prototype.fileDependencies = function()
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.fileDependencies);
|
||||
|
||||
Executable.prototype.setFileDependencies = function(newValue)
|
||||
{
|
||||
this._fileDependencies = newValue;
|
||||
}
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.setFileDependencies);
|
||||
|
||||
Executable.prototype.hasLoadedFileDependencies = function()
|
||||
{
|
||||
return this._fileDependencyStatus === ExecutableLoadedFileDependencies;
|
||||
@@ -278,6 +311,21 @@ Executable.prototype.loadFileDependencies = function(aCallback)
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.loadFileDependencies);
|
||||
|
||||
Executable.prototype.setExecutableUnloadedFileDependencies = function()
|
||||
{
|
||||
if (this._fileDependencyStatus === ExecutableCantStartLoadYetFileDependencies)
|
||||
this._fileDependencyStatus = ExecutableUnloadedFileDependencies;
|
||||
}
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.setExecutableUnloadedFileDependencies);
|
||||
|
||||
Executable.prototype.isExecutableCantStartLoadYetFileDependencies = function()
|
||||
{
|
||||
return this._fileDependencyStatus === ExecutableCantStartLoadYetFileDependencies;
|
||||
}
|
||||
|
||||
DISPLAY_NAME(Executable.prototype.setExecutableUnloadedFileDependencies);
|
||||
|
||||
function loadFileDependenciesForExecutable(/*Executable*/ anExecutable)
|
||||
{
|
||||
fileDependencyExecutables.push(anExecutable);
|
||||
@@ -351,6 +399,7 @@ function fileExecutableDependencyLoadFinished()
|
||||
Executable.prototype.referenceURL = function()
|
||||
{
|
||||
if (this._referenceURL === undefined)
|
||||
// Removed the filename (if any) from the path to get the directory
|
||||
this._referenceURL = new CFURL(".", this.URL());
|
||||
|
||||
return this._referenceURL;
|
||||
@@ -473,11 +522,12 @@ Executable.resetCachedFileExecutableSearchers = function()
|
||||
Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
|
||||
{
|
||||
var referenceURLString = referenceURL.absoluteString(),
|
||||
cachedFileExecutableSearcher = cachedFileExecutableSearchers[referenceURLString],
|
||||
aFilenameTranslateDictionary = Executable.filenameTranslateDictionary ? Executable.filenameTranslateDictionary() : null;
|
||||
cachedFileExecutableSearcher = cachedFileExecutableSearchers[referenceURLString];
|
||||
|
||||
if (!cachedFileExecutableSearcher)
|
||||
{
|
||||
var aFilenameTranslateDictionary = Executable.filenameTranslateDictionary ? Executable.filenameTranslateDictionary() : null;
|
||||
|
||||
cachedFileExecutableSearcher = function(/*CFURL*/ aURL, /*BOOL*/ isQuoted, /*Function*/ success)
|
||||
{
|
||||
var cacheUID = (isQuoted && referenceURL || "") + aURL,
|
||||
@@ -503,7 +553,7 @@ Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
|
||||
if (!aStaticResource)
|
||||
{
|
||||
var compilingFileUrl = exports.ObjJCompiler ? exports.ObjJCompiler.currentCompileFile : null;
|
||||
throw new Error("Could not load file at " + aURL + (compilingFileUrl ? " when compiling " + compilingFileUrl : ""));
|
||||
throw new Error("Could not load file at " + aURL + (compilingFileUrl ? " when compiling " + compilingFileUrl : "") + "\nwith includeURLs: " + StaticResource.includeURLs());
|
||||
}
|
||||
|
||||
cachedFileExecutableSearchResults[cacheUID] = aStaticResource;
|
||||
@@ -519,3 +569,110 @@ Executable.fileExecutableSearcherForURL = function(/*CFURL*/ referenceURL)
|
||||
}
|
||||
|
||||
DISPLAY_NAME(Executable.fileExecutableSearcherForURL);
|
||||
|
||||
/*
|
||||
* Adaption to javascript by Malte Tancred 2012 from ConvertUTF.[ch] by Unicode, Inc.
|
||||
* Speed improvements by Martin Carlberg 2016
|
||||
*
|
||||
* Original copyright follows.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2001-2004 Unicode, Inc.
|
||||
*
|
||||
* Disclaimer
|
||||
*
|
||||
* This source code is provided as is by Unicode, Inc. No claims are
|
||||
* made as to fitness for any particular purpose. No warranties of any
|
||||
* kind are expressed or implied. The recipient agrees to determine
|
||||
* applicability of information provided. If this file has been
|
||||
* purchased on magnetic or optical media from Unicode, Inc., the
|
||||
* sole remedy for any claim will be exchange of defective media
|
||||
* within 90 days of receipt.
|
||||
*
|
||||
* Limitations on Rights to Redistribute This Code
|
||||
*
|
||||
* Unicode, Inc. hereby grants the right to freely use the information
|
||||
* supplied in this file in the creation of products supporting the
|
||||
* Unicode Standard, and to make copies of this file in any form
|
||||
* for internal or external distribution as long as this notice
|
||||
* remains attached.
|
||||
*/
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
|
||||
Conversions between UTF32, UTF-16, and UTF-8. Source code file.
|
||||
Author: Mark E. Davis, 1994.
|
||||
Rev History: Rick McGowan, fixes & updates May 2001.
|
||||
Sept 2001: fixed const & error conditions per
|
||||
mods suggested by S. Parent & A. Lillich.
|
||||
June 2002: Tim Dodd added detection and handling of incomplete
|
||||
source sequences, enhanced error detection, added casts
|
||||
to eliminate compiler warnings.
|
||||
July 2003: slight mods to back out aggressive FFFE detection.
|
||||
Jan 2004: updated switches in from-UTF8 conversions.
|
||||
Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions.
|
||||
|
||||
See the header file "ConvertUTF.h" for complete documentation.
|
||||
|
||||
------------------------------------------------------------------------ */
|
||||
var SURROGATE_HIGH_START = 0xD800;
|
||||
var SURROGATE_HIGH_END = 0xDBFF;
|
||||
var SURROGATE_LOW_START = 0xDC00;
|
||||
var SURROGATE_LOW_END = 0xDFFF;
|
||||
var REPLACEMENT_CHAR = 0xFFFD;
|
||||
var FIRSTBYTEMARK = [0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC];
|
||||
|
||||
function UTF16ToUTF8(source) {
|
||||
var target = "";
|
||||
var currentPos = 0;
|
||||
for (var i = 0; i < source.length; i++) {
|
||||
var c = source.charCodeAt(i);
|
||||
if (c < 0x80) continue;
|
||||
|
||||
if (i > currentPos)
|
||||
target += source.substring(currentPos, i);
|
||||
|
||||
if (c >= SURROGATE_HIGH_START && c <= SURROGATE_HIGH_END) {
|
||||
i++;
|
||||
if (i < source.length) {
|
||||
var c2 = source.charCodeAt(i);
|
||||
if (c2 >= SURROGATE_LOW_START && c2 <= SURROGATE_LOW_END) {
|
||||
c = ((c - SURROGATE_HIGH_START) << 10) + (c2 - SURROGATE_LOW_START) + 0x10000;
|
||||
} else {
|
||||
// illegal second surrogate char
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// missing second surrogate in pair
|
||||
return null;
|
||||
}
|
||||
} else if (c >= SURROGATE_LOW_START && c <= SURROGATE_LOW_END) {
|
||||
// stray surrogate
|
||||
return null;
|
||||
}
|
||||
|
||||
currentPos = i + 1;
|
||||
enc = [];
|
||||
|
||||
var cc = c;
|
||||
|
||||
if (cc >= 0x110000) { cc = 0x800; c = REPLACEMENT_CHAR; }
|
||||
if (cc >= 0x10000) { enc.unshift(String.fromCharCode((c | 0x80) & 0xBF)); c >>= 6; }
|
||||
if (cc >= 0x800) { enc.unshift(String.fromCharCode((c | 0x80) & 0xBF)); c >>= 6; }
|
||||
if (cc >= 0x80) { enc.unshift(String.fromCharCode((c | 0x80) & 0xBF)); c >>= 6; }
|
||||
|
||||
enc.unshift(String.fromCharCode( c | FIRSTBYTEMARK[enc.length]));
|
||||
|
||||
target += enc.join("");
|
||||
}
|
||||
|
||||
if (currentPos === 0) return source;
|
||||
|
||||
if (i > currentPos)
|
||||
target += source.substring(currentPos, i);
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
DISPLAY_NAME(UTF16ToUTF8);
|
||||
|
||||
@@ -49,4 +49,4 @@ FileDependency.prototype.toMarkedString = function()
|
||||
FileDependency.prototype.toString = function()
|
||||
{
|
||||
return (this.isLocal() ? "LOCAL: " : "STD: ") + this.URL();
|
||||
}
|
||||
};
|
||||
|
||||
+144
-34
@@ -41,11 +41,138 @@ function FileExecutable(/*CFURL|String*/ aURL, /*Dictionary*/ aFilenameTranslate
|
||||
executable = NULL,
|
||||
extension = aURL.pathExtension().toLowerCase();
|
||||
|
||||
this._hasExecuted = NO;
|
||||
|
||||
if (fileContents.match(/^@STATIC;/))
|
||||
executable = decompile(fileContents, aURL);
|
||||
else if ((extension === "j" || !extension) && !fileContents.match(/^{/))
|
||||
{
|
||||
var compiler = exports.ObjJCompiler.compileFileDependencies(fileContents, aURL, currentCompilerFlags || {});
|
||||
var compilerOptions = currentCompilerFlags || {};
|
||||
|
||||
this.cachedIncludeFileSearchResultsContent = {};
|
||||
this.cachedIncludeFileSearchResultsURL = {};
|
||||
compile(this, fileContents, aURL, compilerOptions, aFilenameTranslateDictionary);
|
||||
return;
|
||||
}
|
||||
else
|
||||
executable = new Executable(fileContents, [], aURL);
|
||||
|
||||
Executable.apply(this, [executable.code(), executable.fileDependencies(), aURL, executable._function, executable._compiler, aFilenameTranslateDictionary]);
|
||||
}
|
||||
|
||||
exports.FileExecutable = FileExecutable;
|
||||
|
||||
FileExecutable.prototype = new Executable();
|
||||
|
||||
var compile = function(self, fileContents, aURL, compilerOptions, aFilenameTranslateDictionary)
|
||||
{
|
||||
var acornOptions = compilerOptions.acornOptions || (compilerOptions.acornOptions = {});
|
||||
|
||||
acornOptions.preprocessGetIncludeFile = function(filePath, isQuoted) {
|
||||
var referenceURL = new CFURL(".", aURL), // Remove the filename from the url
|
||||
includeURL = new CFURL(filePath);
|
||||
|
||||
var cacheUID = (isQuoted && referenceURL || "") + includeURL,
|
||||
cachedResult = self.cachedIncludeFileSearchResultsContent[cacheUID];
|
||||
|
||||
if (!cachedResult) {
|
||||
var isAbsoluteURL = (includeURL instanceof CFURL) && includeURL.scheme(),
|
||||
compileWhenCompleted = NO;
|
||||
|
||||
function completed(/*StaticResource*/ aStaticResource) {
|
||||
var includeString = aStaticResource && aStaticResource.contents(),
|
||||
lastCharacter = includeString && includeString.charCodeAt(includeString.length - 1);
|
||||
|
||||
if (includeString == null) throw new Error("Can't load file " + includeURL);
|
||||
// Add a new line if the last character is not. If the last thing is a '#define' of other preprocess
|
||||
// token it will not be handled correctly if we don't have a end of line at the end.
|
||||
if (lastCharacter !== 10 && lastCharacter !== 13 && lastCharacter !== 8232 && lastCharacter !== 8233) {
|
||||
includeString += '\n';
|
||||
}
|
||||
|
||||
self.cachedIncludeFileSearchResultsContent[cacheUID] = includeString;
|
||||
self.cachedIncludeFileSearchResultsURL[cacheUID] = aStaticResource.URL();
|
||||
|
||||
if (compileWhenCompleted)
|
||||
compile(self, fileContents, aURL, compilerOptions, aFilenameTranslateDictionary);
|
||||
}
|
||||
|
||||
if (isQuoted || isAbsoluteURL)
|
||||
{
|
||||
if (!isAbsoluteURL)
|
||||
includeURL = new CFURL(includeURL, new CFURL((aFilenameTranslateDictionary[aURL.lastPathComponent()] || "."), referenceURL));
|
||||
|
||||
StaticResource.resolveResourceAtURL(includeURL, NO, completed);
|
||||
}
|
||||
else
|
||||
StaticResource.resolveResourceAtURLSearchingIncludeURLs(includeURL, completed);
|
||||
|
||||
// Now we try to get the cached result again. If we get it then the completed function has already
|
||||
// executed and we can return the include dictionary.
|
||||
cachedResult = self.cachedIncludeFileSearchResultsContent[cacheUID];
|
||||
}
|
||||
|
||||
if (cachedResult) {
|
||||
return {include: cachedResult, sourceFile: self.cachedIncludeFileSearchResultsURL[cacheUID]};
|
||||
} else {
|
||||
// When the file is not available (resolved) return null to tell the parser to throw an exception to exit
|
||||
// Also tell the completed function to compile when finished.
|
||||
compileWhenCompleted = YES
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
var includeFiles = currentCompilerFlags && currentCompilerFlags.includeFiles,
|
||||
allPreIncludesResolved = true;
|
||||
|
||||
acornOptions.preIncludeFiles = [];
|
||||
|
||||
if (includeFiles) for (var i = 0, size = includeFiles.length; i < size; i++)
|
||||
{
|
||||
var includeFileUrl = makeAbsoluteURL(includeFiles[i]);
|
||||
|
||||
try
|
||||
{
|
||||
// try to get all pre include files that acorn will parse before the file from 'aURL'
|
||||
var aResource = StaticResource.resourceAtURL(makeAbsoluteURL(includeFileUrl));
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// Ok, the file is not available (resolved). Resolve all of the files and try again when available.
|
||||
StaticResource.resolveResourcesAtURLs(includeFiles.map(function(u) {return makeAbsoluteURL(u)}), function() {
|
||||
compile(self, fileContents, aURL, compilerOptions, aFilenameTranslateDictionary);
|
||||
});
|
||||
|
||||
allPreIncludesResolved = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (aResource)
|
||||
{
|
||||
if (aResource.isNotFound()) {
|
||||
throw new Error("--include file not found " + includeUrl);
|
||||
}
|
||||
|
||||
var includeString = aResource.contents();
|
||||
var lastCharacter = includeString.charCodeAt(includeString.length - 1);
|
||||
|
||||
// Add a new line if the last character is not. If the last thing is a '#define' of other preprocess
|
||||
// token it will not be handled correctly if we don't have a end of line at the end.
|
||||
if (lastCharacter !== 10 && lastCharacter !== 13 && lastCharacter !== 8232 && lastCharacter !== 8233)
|
||||
includeString += '\n';
|
||||
acornOptions.preIncludeFiles.push({include: includeString, sourceFile: includeFileUrl.toString()});
|
||||
}
|
||||
}
|
||||
|
||||
if (allPreIncludesResolved)
|
||||
{
|
||||
var compiler = exports.ObjJCompiler.compileFileDependencies(fileContents, aURL, compilerOptions);
|
||||
var warningsAndErrors = compiler.warningsAndErrors;
|
||||
|
||||
// Kind of a hack but if we get a file not found error on a #include the get include function above should have asked for the resource
|
||||
// so we should be able to just bail out and wait for the the next call to compile when the include file is loaded (resolved)
|
||||
if (warningsAndErrors && warningsAndErrors.length === 1 && warningsAndErrors[0].message.indexOf("file not found") > -1)
|
||||
return;
|
||||
|
||||
if (FileExecutable.printWarningsAndErrors(compiler, exports.messageOutputFormatInXML))
|
||||
throw "Compilation error";
|
||||
@@ -53,19 +180,25 @@ function FileExecutable(/*CFURL|String*/ aURL, /*Dictionary*/ aFilenameTranslate
|
||||
var fileDependencies = compiler.dependencies.map(function (aFileDep) {
|
||||
return new FileDependency(new CFURL(aFileDep.url), aFileDep.isLocal);
|
||||
});
|
||||
executable = new Executable(compiler.jsBuffer ? compiler.jsBuffer.toString() : null, fileDependencies, compiler.URL, null, compiler);
|
||||
}
|
||||
else
|
||||
executable = new Executable(fileContents, [], aURL);
|
||||
|
||||
Executable.apply(this, [executable.code(), executable.fileDependencies(), aURL, executable._function, executable._compiler, aFilenameTranslateDictionary]);
|
||||
|
||||
this._hasExecuted = NO;
|
||||
if (self.isExecutableCantStartLoadYetFileDependencies())
|
||||
{
|
||||
// Include files that was not loaded has cancelled the compiler so we are already an initialized Executable.
|
||||
// Just set the status so we can start loading the file dependencies.
|
||||
self.setFileDependencies(fileDependencies);
|
||||
self.setExecutableUnloadedFileDependencies();
|
||||
self.loadFileDependencies();
|
||||
}
|
||||
else if (self._fileDependencyStatus == null)
|
||||
{
|
||||
// Are we still a FileExecutable. Call 'super' init method to make us a initilized subclass of an Executable.
|
||||
executable = new Executable(compiler && compiler.jsBuffer ? compiler.jsBuffer.toString() : null, fileDependencies, aURL, null, compiler);
|
||||
Executable.apply(self, [executable.code(), executable.fileDependencies(), aURL, executable._function, executable._compiler, aFilenameTranslateDictionary]);
|
||||
}
|
||||
}
|
||||
|
||||
exports.FileExecutable = FileExecutable;
|
||||
|
||||
FileExecutable.prototype = new Executable();
|
||||
DISPLAY_NAME(compile);
|
||||
|
||||
#ifdef COMMONJS
|
||||
FileExecutable.allFileExecutables = function()
|
||||
@@ -159,30 +292,7 @@ FileExecutable.setCurrentGccCompilerFlags = function(/*String*/ compilerFlags)
|
||||
|
||||
currentGccCompilerFlags = compilerFlags;
|
||||
|
||||
var args = compilerFlags.split(" "),
|
||||
count = args.length,
|
||||
objjcFlags = {};
|
||||
|
||||
for (var index = 0; index < count; ++index)
|
||||
{
|
||||
var argument = args[index];
|
||||
|
||||
if (argument.indexOf("-g") === 0)
|
||||
objjcFlags.includeMethodFunctionNames = true;
|
||||
else if (argument.indexOf("-O") === 0) {
|
||||
objjcFlags.inlineMsgSendFunctions = true;
|
||||
// FIXME: currently we are sending in '-O2' when we want InlineMsgSend. Here we only check if it is '-O...'.
|
||||
// Maybe we should have some other option for this
|
||||
if (argument.length > 2)
|
||||
objjcFlags.inlineMsgSendFunctions = true;
|
||||
}
|
||||
//else if (argument.indexOf("-G") === 0)
|
||||
//objjcFlags |= ObjJAcornCompiler.Flags.Generate;
|
||||
else if (argument.indexOf("-T") === 0) {
|
||||
objjcFlags.includeIvarTypeSignatures = false;
|
||||
objjcFlags.includeMethodArgumentTypeSignatures = false;
|
||||
}
|
||||
}
|
||||
var objjcFlags = exports.ObjJCompiler.parseGccCompilerFlags(compilerFlags);
|
||||
|
||||
FileExecutable.setCurrentCompilerFlags(objjcFlags);
|
||||
}
|
||||
|
||||
+34
-12
@@ -26,6 +26,13 @@ var FILE = require("file"),
|
||||
OS = require("os"),
|
||||
stream = require("narwhal/term").stream;
|
||||
|
||||
var walk = require("./acornwalk").acorn.walk;
|
||||
|
||||
acorn = {walk: walk};
|
||||
acorn = require("./acorn").acorn;
|
||||
|
||||
var compiler = require("./ObjJAcornCompiler").ObjJCompiler;
|
||||
|
||||
//$BUILD_CONFIGURATION_DIR = "../Build"
|
||||
$BROWSER_FILE = FILE.join("Browser", "Objective-J.js");
|
||||
|
||||
@@ -106,7 +113,7 @@ function environmentFlags()
|
||||
|
||||
return environments.map(function(anEnvironment) {
|
||||
return "-D" + anEnvironment.toUpperCase();
|
||||
}).concat("-DENVIRONMENTS=" + OS.enquote(JSON.stringify(environments)));
|
||||
}).concat("-DENVIRONMENTS=" + JSON.stringify(environments));
|
||||
}
|
||||
|
||||
var SHRINKSAFE = require("minify/shrinksafe");
|
||||
@@ -114,26 +121,41 @@ function compressor(code) {
|
||||
return SHRINKSAFE.compress(code, { charset : "UTF-8", useServer : true });
|
||||
}
|
||||
|
||||
var headerText = FILE.read("header.txt", { charset : "UTF-8" });
|
||||
function gcc(inputFilePath, outputFilePath, flags, compress)
|
||||
{
|
||||
stream.print("Building... \0green(" + outputFilePath +"\0)");
|
||||
|
||||
// GCC preprocess the file.
|
||||
var cmd = ["gcc", "-E", "-x", "c", "-P"].concat(flags, inputFilePath).join(" "),
|
||||
contents = FILE.read("header.txt", { charset : "UTF-8" });
|
||||
var source = FILE.read(inputFilePath, { charset : "UTF-8" });
|
||||
var compilerOptions = compiler.parseGccCompilerFlags(flags.join(" "));
|
||||
var acornOptions = compilerOptions.acornOptions || (compilerOptions.acornOptions = {});
|
||||
|
||||
try
|
||||
{
|
||||
var gcc = OS.popen(cmd, { charset:"UTF-8" });
|
||||
contents += gcc.stdout.read();
|
||||
acornOptions.preprocessGetIncludeFile = function(filePath, isQuoted) {
|
||||
var includeContent = FILE.read(filePath, { charset : "UTF-8" });
|
||||
//print ("Include content for file '" + filePath + "': " + includeContent);
|
||||
//print ("Include file '" + filePath + "'");
|
||||
return {include: includeContent, sourceFile: filePath};
|
||||
}
|
||||
finally
|
||||
|
||||
var c = compiler.compile(source, inputFilePath, compilerOptions);
|
||||
var warnings = [],
|
||||
anyErrors = false;
|
||||
|
||||
for (var i = 0; i < c.warningsAndErrors.length; i++)
|
||||
{
|
||||
gcc.stdin.close();
|
||||
gcc.stdout.close();
|
||||
gcc.stderr.close();
|
||||
var warning = c.warningsAndErrors[i],
|
||||
message = c.prettifyMessage(warning);
|
||||
|
||||
// Set anyErrors to 'true' if there are any errors in the list
|
||||
anyErrors = anyErrors || warning.messageType === "ERROR";
|
||||
print(message);
|
||||
}
|
||||
|
||||
if (anyErrors) throw "Compilation Error";
|
||||
|
||||
var code = c.code();
|
||||
var contents = headerText + code;
|
||||
|
||||
if (FILE.extension(inputFilePath) === ".js" && compress)
|
||||
contents = compressor(contents);
|
||||
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
|
||||
(function(mod)
|
||||
{
|
||||
//print("Compiler INIT! exports: " + typeof exports + ", module: " + typeof module + ", define: " + typeof define);
|
||||
mod(exports.ObjJCompiler || (exports.ObjJCompiler = {}), exports.acorn, exports.acorn.walk/*, sourceMap*/); // Plain browser env
|
||||
mod(exports.ObjJCompiler || (exports.ObjJCompiler = {}), exports.acorn || acorn, (exports.acorn || acorn).walk, typeof sourceMap != "undefined" ? sourceMap : null); // Plain browser env
|
||||
})(function(exports, acorn, walk, sourceMap)
|
||||
{
|
||||
"use strict";
|
||||
|
||||
exports.version = "0.3.7";
|
||||
//exports.acorn = acorn;
|
||||
|
||||
var Scope = function(prev, base)
|
||||
{
|
||||
@@ -280,7 +278,7 @@ GlobalVariableMaybeWarning.prototype.isEqualTo = function(/* GlobalVariableMaybe
|
||||
return true;
|
||||
}
|
||||
|
||||
function StringBuffer(useSourceNode, file)
|
||||
function StringBuffer(useSourceNode, file, sourceContent)
|
||||
{
|
||||
if (useSourceNode) {
|
||||
this.rootNode = new sourceMap.SourceNode();
|
||||
@@ -289,8 +287,21 @@ function StringBuffer(useSourceNode, file)
|
||||
this.isEmpty = this.isEmptySourceNode;
|
||||
this.appendStringBuffer = this.appendStringBufferSourceNode;
|
||||
this.length = this.lengthSourceNode;
|
||||
if (file)
|
||||
this.file = file.toString();
|
||||
if (file) {
|
||||
var fileString = file.toString(),
|
||||
filename = fileString.substr(fileString.lastIndexOf('/') + 1),
|
||||
sourceRoot = fileString.substr(0, fileString.lastIndexOf('/') + 1);
|
||||
|
||||
this.filename = filename;
|
||||
|
||||
if (sourceRoot.length > 0)
|
||||
this.sourceRoot = sourceRoot;
|
||||
if (sourceContent != null)
|
||||
this.rootNode.setSourceContent(filename, sourceContent);
|
||||
}
|
||||
|
||||
if (sourceContent != null)
|
||||
this.sourceContent = sourceContent;
|
||||
} else {
|
||||
this.atoms = [];
|
||||
this.concat = this.concatString;
|
||||
@@ -308,7 +319,7 @@ StringBuffer.prototype.toStringString = function()
|
||||
|
||||
StringBuffer.prototype.toStringSourceNode = function()
|
||||
{
|
||||
return this.rootNode.toStringWithSourceMap({file: this.file});
|
||||
return this.rootNode.toStringWithSourceMap({file: this.filename + "s", sourceRoot:this.sourceRoot});
|
||||
}
|
||||
|
||||
StringBuffer.prototype.concatString = function(aString)
|
||||
@@ -316,11 +327,11 @@ StringBuffer.prototype.concatString = function(aString)
|
||||
this.atoms.push(aString);
|
||||
}
|
||||
|
||||
StringBuffer.prototype.concatSourceNode = function(aString, node)
|
||||
StringBuffer.prototype.concatSourceNode = function(aString, node, originalName)
|
||||
{
|
||||
if (node) {
|
||||
//console.log("Snippet: " + aString + ", line: " + node.loc.start.line + ", column: " + node.loc.start.column + ", source: " + node.loc.source);
|
||||
this.rootNode.add(new sourceMap.SourceNode(node.loc.start.line, node.loc.start.column, node.loc.source, aString));
|
||||
this.rootNode.add(new sourceMap.SourceNode(node.loc.start.line, node.loc.start.column, node.loc.source, aString, originalName));
|
||||
} else
|
||||
this.rootNode.add(aString);
|
||||
if (!this.notEmpty)
|
||||
@@ -624,10 +635,13 @@ var isInInstanceof = acorn.makePredicate("in instanceof");
|
||||
// Turn on `sourceMap` generate a source map for the compiler file.
|
||||
sourceMap: false,
|
||||
|
||||
// Turn on `sourceMapIncludeSource` will include the source code in the source map.
|
||||
sourceMapIncludeSource: false,
|
||||
|
||||
// The compiler can do different passes.
|
||||
// 1: Parse and walk AST tree to collect file dependencies.
|
||||
// 2: Parse and walk to generate code.
|
||||
// Pass one is only for when the Objective-J load and runtime.
|
||||
// Pass one is only for the Objective-J load and runtime.
|
||||
pass: 2,
|
||||
|
||||
// Pass in class definitions. New class definitions in source file will be added here when compiling.
|
||||
@@ -678,6 +692,12 @@ var isInInstanceof = acorn.makePredicate("in instanceof");
|
||||
|
||||
// Turn off `inlineMsgSendFunctions` to use message send functions. Needed to use message send decorators.
|
||||
inlineMsgSendFunctions: true,
|
||||
|
||||
// An array of macro objects and/or text definitions may be passed in.
|
||||
// Definitions may be in one of two forms:
|
||||
// macro
|
||||
// macro=body
|
||||
macros: null,
|
||||
};
|
||||
|
||||
// We copy the options to a new object as we don't want to mess up incoming options when we start compiling.
|
||||
@@ -710,7 +730,7 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, options)
|
||||
this.formatDescription = options.formatDescription;
|
||||
this.includeComments = options.includeComments;
|
||||
this.transformNamedFunctionDeclarationToAssignment = options.transformNamedFunctionDeclarationToAssignment;
|
||||
this.jsBuffer = new StringBuffer(this.createSourceMap, aURL);
|
||||
this.jsBuffer = new StringBuffer(this.createSourceMap, aURL, options.sourceMap && options.sourceMapIncludeSource ? this.source : null);
|
||||
this.imBuffer = null;
|
||||
this.cmBuffer = null;
|
||||
this.dependencies = [];
|
||||
@@ -727,7 +747,7 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, options)
|
||||
|
||||
if (acornOptions)
|
||||
{
|
||||
if (!acornOptions.sourceFile && this.URL)
|
||||
if (this.URL)
|
||||
acornOptions.sourceFile = this.URL.substr(this.URL.lastIndexOf('/') + 1);
|
||||
if (options.sourceMap && !acornOptions.locations)
|
||||
acornOptions.locations = true;
|
||||
@@ -739,6 +759,14 @@ var ObjJAcornCompiler = function(/*String*/ aString, /*CFURL*/ aURL, options)
|
||||
acornOptions.locations = true;
|
||||
}
|
||||
|
||||
if (options.macros)
|
||||
{
|
||||
if (acornOptions.macros)
|
||||
acornOptions.macros.concat(options.macros);
|
||||
else
|
||||
acornOptions.macros = options.macros;
|
||||
}
|
||||
|
||||
try {
|
||||
this.tokens = acorn.parse(aString, options.acornOptions);
|
||||
(this.pass === 2 && (options.includeComments || options.formatDescription) ? compileWithFormat : compile)(this.tokens, new Scope(null ,{ compiler: this }), this.pass === 2 ? pass2 : pass1);
|
||||
@@ -795,14 +823,16 @@ exports.compileFileDependencies = function(/*String*/ aString, /*CFURL*/ aURL, o
|
||||
|
||||
ObjJAcornCompiler.prototype.compilePass2 = function()
|
||||
{
|
||||
var options = this.options;
|
||||
|
||||
exports.currentCompileFile = this.URL;
|
||||
this.pass = this.options.pass = 2;
|
||||
this.jsBuffer = new StringBuffer(this.createSourceMap, this.URL);
|
||||
this.pass = options.pass = 2;
|
||||
this.jsBuffer = new StringBuffer(this.createSourceMap, this.URL, options.sourceMap && options.sourceMapIncludeSource ? this.source : null);
|
||||
|
||||
// To get the source mapping correct when the new Function construtor is used we add a
|
||||
// new line as first thing in the code.
|
||||
if (this.createSourceMap)
|
||||
this.jsBuffer.concat("\n");
|
||||
this.jsBuffer.concat("\n\n");
|
||||
|
||||
this.warningsAndErrors = [];
|
||||
try {
|
||||
@@ -959,6 +989,76 @@ ObjJAcornCompiler.prototype.getTypeDef = function(/* String */ aTypeDefName)
|
||||
return null;
|
||||
}
|
||||
|
||||
/*!
|
||||
Return a parsed option dictionary
|
||||
*/
|
||||
exports.parseGccCompilerFlags = function(/* String */ compilerFlags)
|
||||
{
|
||||
var args = (compilerFlags || "").split(" "),
|
||||
count = args.length,
|
||||
objjcFlags = {};
|
||||
|
||||
for (var index = 0; index < count; ++index)
|
||||
{
|
||||
var argument = args[index];
|
||||
|
||||
if (argument.indexOf("-g") === 0)
|
||||
objjcFlags.includeMethodFunctionNames = true;
|
||||
else if (argument.indexOf("-O") === 0) {
|
||||
objjcFlags.inlineMsgSendFunctions = true;
|
||||
// FIXME: currently we are sending in '-O2' when we want InlineMsgSend. Here we only check if it is '-O...'.
|
||||
// Maybe we should have some other option for this
|
||||
if (argument.length > 2)
|
||||
objjcFlags.inlineMsgSendFunctions = true;
|
||||
}
|
||||
//else if (argument.indexOf("-G") === 0)
|
||||
//objjcFlags |= ObjJAcornCompiler.Flags.Generate;
|
||||
else if (argument.indexOf("-T") === 0) {
|
||||
objjcFlags.includeIvarTypeSignatures = false;
|
||||
objjcFlags.includeMethodArgumentTypeSignatures = false;
|
||||
}
|
||||
else if (argument.indexOf("-S") === 0) {
|
||||
objjcFlags.sourceMap = true;
|
||||
objjcFlags.sourceMapIncludeSource = true;
|
||||
}
|
||||
else if (argument.indexOf("--include") === 0) {
|
||||
var includeUrl = args[++index],
|
||||
firstChar = includeUrl && includeUrl.charCodeAt(0);
|
||||
|
||||
// Poor mans unquote
|
||||
if (firstChar === 34 || firstChar === 39) // '"', "'"
|
||||
includeUrl = includeUrl.substring(1, includeUrl.length - 1);
|
||||
|
||||
(objjcFlags.includeFiles || (objjcFlags.includeFiles = [])).push(includeUrl);
|
||||
}
|
||||
/* else if (argument.indexOf("-I") === 0) {
|
||||
var includeUrl = argument.substring(2),
|
||||
firstChar = includeUrl && includeUrl.charCodeAt(0);
|
||||
|
||||
(objjcFlags.includeFiles || (objjcFlags.includeFiles = [])).push(includeUrl);
|
||||
}
|
||||
else if (argument.indexOf("'-I") === 0) {
|
||||
var includeUrl = argument.substring(3, argument.length - 1),
|
||||
firstChar = includeUrl && includeUrl.charCodeAt(0);
|
||||
|
||||
(objjcFlags.includeFiles || (objjcFlags.includeFiles = [])).push(includeUrl);
|
||||
}
|
||||
else if (argument.indexOf('"-I') === 0) {
|
||||
var includeUrl = argument.substring(3, argument.length - 1),
|
||||
firstChar = includeUrl && includeUrl.charCodeAt(0);
|
||||
|
||||
(objjcFlags.includeFiles || (objjcFlags.includeFiles = [])).push(includeUrl);
|
||||
}*/
|
||||
else if (argument.indexOf("-D") === 0) {
|
||||
var macroDefinition = argument.substring(2);
|
||||
|
||||
(objjcFlags.macros || (objjcFlags.macros = [])).push(macroDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
return objjcFlags;
|
||||
}
|
||||
|
||||
ObjJAcornCompiler.methodDefsFromMethodList = function(/* Array */ methodList)
|
||||
{
|
||||
var methodSize = methodList.length,
|
||||
@@ -1006,10 +1106,10 @@ ObjJAcornCompiler.prototype.map = function()
|
||||
ObjJAcornCompiler.prototype.prettifyMessage = function(/* Message */ aMessage)
|
||||
{
|
||||
var line = aMessage.messageForLine,
|
||||
message = "\n" + line;
|
||||
message = "\n" + (line || "");
|
||||
|
||||
message += (new Array(aMessage.messageOnColumn + 1)).join(" ");
|
||||
message += (new Array(Math.min(1, line.length) + 1)).join("^") + "\n";
|
||||
message += (new Array((aMessage.messageOnColumn || 0) + 1)).join(" ");
|
||||
if (line) message += (new Array(Math.min(1, line.length || 1) + 1)).join("^") + "\n";
|
||||
message += aMessage.messageType + " line " + aMessage.messageOnLine + " in " + this.URL + ": " + aMessage.message;
|
||||
|
||||
return message;
|
||||
@@ -1309,13 +1409,13 @@ BlockStatement: function(node, st, c, format) {
|
||||
}
|
||||
|
||||
//Simulate a node for the last curly bracket
|
||||
var endNode = node.loc && { loc: { start: { line : node.loc.end.line, column: node.loc.end.column-1}}, source: node.loc.source};
|
||||
// var endNode = node.loc && { loc: { start: { line : node.loc.end.line, column: node.loc.end.column}}, source: node.loc.source};
|
||||
if (format) {
|
||||
buffer.concatFormat(format.beforeRightBrace);
|
||||
buffer.concat("}", endNode);
|
||||
buffer.concat("}", node);
|
||||
} else {
|
||||
buffer.concat(indentation.substring(indentationSize));
|
||||
buffer.concat("}", endNode);
|
||||
buffer.concat("}", node);
|
||||
if (!skipIndentation && st.isDecl !== false)
|
||||
buffer.concat("\n");
|
||||
st.indentBlockLevel--;
|
||||
@@ -1351,11 +1451,11 @@ IfStatement: function(node, st, c, format) {
|
||||
c(node.test, st, "Expression");
|
||||
if (generate) {
|
||||
if (format) {
|
||||
buffer.concat(")");
|
||||
buffer.concat(")", node);
|
||||
buffer.concatFormat(format.afterRightParenthesis);
|
||||
} else {
|
||||
// We don't want EmptyStatements to generate an extra parenthesis except when it is in a while, for, ...
|
||||
buffer.concat(node.consequent.type === "EmptyStatement" ? ");\n" : ")\n");
|
||||
buffer.concat(node.consequent.type === "EmptyStatement" ? ");\n" : ")\n", node);
|
||||
}
|
||||
}
|
||||
indentation += indentStep;
|
||||
@@ -1367,13 +1467,13 @@ IfStatement: function(node, st, c, format) {
|
||||
if (generate) {
|
||||
if (format) {
|
||||
buffer.concatFormat(format.beforeElse); // Do we need this?
|
||||
buffer.concat("else");
|
||||
buffer.concat("else", node);
|
||||
buffer.concatFormat(format.afterElse);
|
||||
} else {
|
||||
var emptyStatement = alternate.type === "EmptyStatement";
|
||||
buffer.concat(indentation);
|
||||
// We don't want EmptyStatements to generate an extra parenthesis except when it is in a while, for, ...
|
||||
buffer.concat(alternateNotIf ? emptyStatement ? "else;\n" : "else\n" : "else ");
|
||||
buffer.concat(alternateNotIf ? emptyStatement ? "else;\n" : "else\n" : "else ", node);
|
||||
}
|
||||
}
|
||||
if (alternateNotIf)
|
||||
@@ -1392,10 +1492,10 @@ LabeledStatement: function(node, st, c, format) {
|
||||
if (!format) buffer.concat(indentation);
|
||||
c(node.label, st, "IdentifierName");
|
||||
if (format) {
|
||||
buffer.concat(":");
|
||||
buffer.concat(":", node);
|
||||
buffer.concatFormat(format.afterColon);
|
||||
} else {
|
||||
buffer.concat(": ");
|
||||
buffer.concat(": ", node);
|
||||
}
|
||||
}
|
||||
c(node.body, st, "Statement");
|
||||
@@ -1456,10 +1556,10 @@ WithStatement: function(node, st, c, format) {
|
||||
c(node.object, st, "Expression");
|
||||
if (generate)
|
||||
if (format) {
|
||||
buffer.concat(")");
|
||||
buffer.concat(")", node);
|
||||
buffer.concatFormat(format.afterRightParenthesis);
|
||||
} else {
|
||||
buffer.concat(")\n");
|
||||
buffer.concat(")\n", node);
|
||||
}
|
||||
indentation += indentStep;
|
||||
c(node.body, st, "Statement");
|
||||
@@ -1968,7 +2068,7 @@ SequenceExpression: function(node, st, c, format) {
|
||||
buffer;
|
||||
if (generate) {
|
||||
buffer = compiler.jsBuffer;
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
}
|
||||
for (var i = 0; i < node.expressions.length; ++i) {
|
||||
if (generate && i !== 0)
|
||||
@@ -2079,7 +2179,7 @@ AssignmentExpression: function(node, st, c, format) {
|
||||
if (!generate) buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
|
||||
// Output the dereference function, "(...)(z)"
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
// What's being dereferenced could itself be an expression, such as when dereferencing a deref.
|
||||
if (!generate) compiler.lastPos = node.left.expr.start;
|
||||
c(node.left.expr, st, "Expression");
|
||||
@@ -2269,7 +2369,7 @@ Identifier: function(node, st, c) {
|
||||
st.addMaybeWarning(message);
|
||||
}
|
||||
}
|
||||
if (generate) compiler.jsBuffer.concat(identifier, node);
|
||||
if (generate) compiler.jsBuffer.concat(identifier, node, "self");
|
||||
},
|
||||
// Use this when there should not be a look up to issue warnings or add 'self.' before ivars
|
||||
IdentifierName: function(node, st, c) {
|
||||
@@ -2316,7 +2416,7 @@ ArrayLiteral: function(node, st, c) {
|
||||
buffer.concat("@[");
|
||||
} else if (!elementLength) {
|
||||
if (compiler.options.inlineMsgSendFunctions) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPArray.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2341,7 +2441,7 @@ ArrayLiteral: function(node, st, c) {
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
} else {
|
||||
if (compiler.options.inlineMsgSendFunctions) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPArray.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2351,7 +2451,7 @@ ArrayLiteral: function(node, st, c) {
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:count:\", [");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPArray.isa.objj_msgSend0(CPArray, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2410,7 +2510,7 @@ DictionaryLiteral: function(node, st, c) {
|
||||
buffer.concat("}");
|
||||
} else if (!keyLength) {
|
||||
if (compiler.options.inlineMsgSendFunctions) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPDictionary.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2435,7 +2535,7 @@ DictionaryLiteral: function(node, st, c) {
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
} else {
|
||||
if (compiler.options.inlineMsgSendFunctions) {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = (CPDictionary.isa.method_msgSend[\"alloc\"] || _objj_forward)(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2445,7 +2545,7 @@ DictionaryLiteral: function(node, st, c) {
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(", \"initWithObjects:forKeys:\", [");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat("(___r", node);
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = CPDictionary.isa.objj_msgSend0(CPDictionary, \"alloc\"), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
@@ -2515,10 +2615,11 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
classScope = new Scope(st),
|
||||
isInterfaceDeclaration = node.type === "InterfaceDeclarationStatement",
|
||||
protocols = node.protocols,
|
||||
generateObjJ = compiler.options.generateObjJ;
|
||||
options = compiler.options,
|
||||
generateObjJ = options.generateObjJ;
|
||||
|
||||
compiler.imBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL);
|
||||
compiler.cmBuffer = new StringBuffer(compiler.createSourceMap), compiler.URL;
|
||||
compiler.imBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL, options.sourceMap && options.sourceMapIncludeSource ? compiler.source : null);
|
||||
compiler.cmBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL);
|
||||
compiler.classBodyBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL); // TODO: Check if this is needed
|
||||
|
||||
if (compiler.getTypeDef(className))
|
||||
@@ -2660,7 +2761,7 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
else
|
||||
saveJSBuffer.concat(", ");
|
||||
|
||||
if (compiler.options.includeIvarTypeSignatures)
|
||||
if (options.includeIvarTypeSignatures)
|
||||
saveJSBuffer.concat("new objj_ivar(\"" + ivarName + "\", \"" + ivarType + "\")", node);
|
||||
else
|
||||
saveJSBuffer.concat("new objj_ivar(\"" + ivarName + "\")", node);
|
||||
@@ -2708,7 +2809,8 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
// If we have accessors add get and set methods for them
|
||||
if (!generateObjJ && !isInterfaceDeclaration && hasAccessors)
|
||||
{
|
||||
var getterSetterBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL);
|
||||
// We pass false to the string buffer as we don't need source map when we create the Objective-J code for the accessors
|
||||
var getterSetterBuffer = new StringBuffer(false);
|
||||
|
||||
// Add the class declaration to compile accessors correctly
|
||||
// Remove all protocols from class declaration
|
||||
@@ -2727,7 +2829,7 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
|
||||
var property = (accessors.property && accessors.property.name) || ivarName,
|
||||
getterName = (accessors.getter && accessors.getter.name) || property,
|
||||
getterCode = "- (" + (ivarType ? ivarType : "id") + ")" + getterName + "\n{\nreturn " + ivarName + ";\n}\n";
|
||||
getterCode = "- (" + (ivarType ? ivarType : "id") + ")" + getterName + "\n{\n return " + ivarName + ";\n}\n";
|
||||
|
||||
getterSetterBuffer.concat(getterCode);
|
||||
|
||||
@@ -2743,10 +2845,10 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
setterName = (start ? "_" : "") + "set" + property.substr(start, 1).toUpperCase() + property.substring(start + 1) + ":";
|
||||
}
|
||||
|
||||
var setterCode = "- (void)" + setterName + "(" + (ivarType ? ivarType : "id") + ")newValue\n{\n";
|
||||
var setterCode = "- (void)" + setterName + "(" + (ivarType ? ivarType : "id") + ")newValue\n{\n ";
|
||||
|
||||
if (accessors.copy)
|
||||
setterCode += "if (" + ivarName + " !== newValue)\n" + ivarName + " = [newValue copy];\n}\n";
|
||||
setterCode += "if (" + ivarName + " !== newValue)\n " + ivarName + " = [newValue copy];\n}\n";
|
||||
else
|
||||
setterCode += ivarName + " = newValue;\n}\n";
|
||||
|
||||
@@ -2757,11 +2859,26 @@ ClassDeclarationStatement: function(node, st, c, format) {
|
||||
|
||||
// Remove all @accessors or we will get a recursive loop in infinity
|
||||
var b = getterSetterBuffer.toString().replace(/@accessors(\(.*\))?/g, "");
|
||||
var imBuffer = exports.compileToIMBuffer(b, "Accessors", compiler.options);
|
||||
var compilerOptions = setupOptions(options);
|
||||
|
||||
compilerOptions.sourceMapIncludeSource = true;
|
||||
var url = compiler.url;
|
||||
var filename = url && compiler.URL.substr(compiler.URL.lastIndexOf('/') + 1);
|
||||
var dotIndex = filename && filename.lastIndexOf(".");
|
||||
var filenameNoExt = filename && (filename.substr(0, dotIndex === -1 ? filename.length : dotIndex));
|
||||
var filenameExt = filename && filename.substr(dotIndex === -1 ? filename.length : dotIndex);
|
||||
var categoryname = node.categoryname && node.categoryname.id;
|
||||
var imBuffer = exports.compileToIMBuffer(b, filenameNoExt + "_" + className + (categoryname ? "_" + categoryname : "") + "_Accessors" + (filenameExt || ""), compilerOptions);
|
||||
|
||||
// Add the accessors methods first to instance method buffer.
|
||||
// This will allow manually added set and get methods to override the compiler generated
|
||||
compiler.imBuffer.concat(imBuffer);
|
||||
var generatedCode = imBuffer.toString();
|
||||
|
||||
if (compiler.createSourceMap) {
|
||||
compiler.imBuffer.concat(sourceMap.SourceNode.fromStringWithSourceMap(generatedCode.code, sourceMap.SourceMapConsumer(generatedCode.map.toString())));
|
||||
} else {
|
||||
compiler.imBuffer.concat(generatedCode);
|
||||
}
|
||||
}
|
||||
|
||||
// We will store the ivars into the classDef first after accessors are done so we don't get a duplicate ivars error when generating accessors
|
||||
@@ -2865,7 +2982,7 @@ ProtocolDeclarationStatement: function(node, st, c) {
|
||||
throw compiler.error_message("Duplicate protocol " + protocolName, node.protocolname);
|
||||
|
||||
compiler.imBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL);
|
||||
compiler.cmBuffer = new StringBuffer(compiler.createSourceMap), compiler.URL;
|
||||
compiler.cmBuffer = new StringBuffer(compiler.createSourceMap, compiler.URL);
|
||||
|
||||
if (!generate) buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
|
||||
@@ -3227,17 +3344,17 @@ MessageSendExpression: function(node, st, c) {
|
||||
buffer.concat("[super ");
|
||||
} else {
|
||||
if (inlineMsgSend) {
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
buffer.concat(st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass);
|
||||
buffer.concat(".method_dtable[\"");
|
||||
buffer.concat(".method_dtable[\"", node);
|
||||
buffer.concat(selector);
|
||||
buffer.concat("\"] || _objj_forward)(self");
|
||||
buffer.concat("\"] || _objj_forward)(self", node);
|
||||
} else {
|
||||
buffer.concat("objj_msgSendSuper");
|
||||
buffer.concat("objj_msgSendSuper", node);
|
||||
if (totalNoOfParameters < 4) {
|
||||
buffer.concat("" + totalNoOfParameters);
|
||||
}
|
||||
buffer.concat("({ receiver:self, super_class:" + (st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass ) + " }");
|
||||
buffer.concat("({ receiver:self, super_class:" + (st.currentMethodType() === "+" ? compiler.currentSuperMetaClass : compiler.currentSuperClass ) + " }", node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3261,36 +3378,35 @@ MessageSendExpression: function(node, st, c) {
|
||||
}
|
||||
|
||||
if (receiverIsNotSelf) {
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
c(nodeObject, st, "Expression");
|
||||
buffer.concat(" == null ? null : ");
|
||||
buffer.concat(" == null ? null : ", node);
|
||||
}
|
||||
if (inlineMsgSend)
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
c(nodeObject, st, "Expression");
|
||||
} else {
|
||||
receiverIsNotSelf = true;
|
||||
if (!st.receiverLevel) st.receiverLevel = 0;
|
||||
buffer.concat("((___r");
|
||||
buffer.concat(++st.receiverLevel + "");
|
||||
buffer.concat(" = ");
|
||||
buffer.concat("((___r" + ++st.receiverLevel, node);
|
||||
buffer.concat(" = ", node);
|
||||
c(nodeObject, st, "Expression");
|
||||
buffer.concat("), ___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat(" == null ? null : ");
|
||||
buffer.concat(")", node);
|
||||
buffer.concat(", ___r" + st.receiverLevel, node);
|
||||
buffer.concat(" == null ? null : ", node);
|
||||
if (inlineMsgSend)
|
||||
buffer.concat("(");
|
||||
buffer.concat("___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat("(", node);
|
||||
buffer.concat("___r" + st.receiverLevel, node);
|
||||
if (!(st.maxReceiverLevel >= st.receiverLevel))
|
||||
st.maxReceiverLevel = st.receiverLevel;
|
||||
}
|
||||
if (inlineMsgSend) {
|
||||
buffer.concat(".isa.method_msgSend[\"");
|
||||
buffer.concat(selector);
|
||||
buffer.concat("\"] || _objj_forward)");
|
||||
} else
|
||||
buffer.concat(".isa.objj_msgSend");
|
||||
buffer.concat(".isa.method_msgSend[\"", node);
|
||||
buffer.concat(selector, node);
|
||||
buffer.concat("\"] || _objj_forward)", node);
|
||||
} else {
|
||||
buffer.concat(".isa.objj_msgSend", node);
|
||||
}
|
||||
} else {
|
||||
buffer.concat(" "); // Add an extra space if it looks something like this: "return(<expression>)". No space between return and expression.
|
||||
buffer.concat("objj_msgSend(");
|
||||
@@ -3325,28 +3441,27 @@ MessageSendExpression: function(node, st, c) {
|
||||
if (generate && !node.superObject) {
|
||||
if (!inlineMsgSend) {
|
||||
if (totalNoOfParameters < 4) {
|
||||
buffer.concat("" + totalNoOfParameters);
|
||||
buffer.concat("" + totalNoOfParameters, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (receiverIsIdentifier) {
|
||||
buffer.concat("(");
|
||||
buffer.concat("(", node);
|
||||
c(nodeObject, st, "Expression");
|
||||
} else {
|
||||
buffer.concat("(___r");
|
||||
buffer.concat(st.receiverLevel + "");
|
||||
buffer.concat("(___r" + st.receiverLevel, node);
|
||||
}
|
||||
}
|
||||
|
||||
buffer.concat(", \"");
|
||||
buffer.concat(", \"", node);
|
||||
buffer.concat(selector); // FIXME: sel_getUid(selector + "") ? This FIXME is from the old preprocessor compiler
|
||||
buffer.concat("\"");
|
||||
buffer.concat("\"", node);
|
||||
|
||||
if (nodeArguments) for (var i = 0; i < nodeArguments.length; i++)
|
||||
{
|
||||
var argument = nodeArguments[i];
|
||||
|
||||
buffer.concat(", ");
|
||||
buffer.concat(", ", node);
|
||||
if (!generate)
|
||||
compiler.lastPos = argument.start;
|
||||
c(argument, st, "Expression");
|
||||
@@ -3360,7 +3475,7 @@ MessageSendExpression: function(node, st, c) {
|
||||
{
|
||||
var parameter = parameters[i];
|
||||
|
||||
buffer.concat(", ");
|
||||
buffer.concat(", ", node);
|
||||
if (!generate)
|
||||
compiler.lastPos = parameter.start;
|
||||
c(parameter, st, "Expression");
|
||||
@@ -3372,12 +3487,12 @@ MessageSendExpression: function(node, st, c) {
|
||||
|
||||
if (generate && !node.superObject) {
|
||||
if (receiverIsNotSelf)
|
||||
buffer.concat(")");
|
||||
buffer.concat(")", node);
|
||||
if (!receiverIsIdentifier)
|
||||
st.receiverLevel--;
|
||||
}
|
||||
|
||||
buffer.concat(")");
|
||||
buffer.concat(")", node);
|
||||
}
|
||||
|
||||
if (!generate) compiler.lastPos = node.end;
|
||||
@@ -3525,7 +3640,7 @@ TypeDefStatement: function(node, st, c) {
|
||||
if (!generate)
|
||||
buffer.concat(compiler.source.substring(compiler.lastPos, node.start));
|
||||
|
||||
buffer.concat("{var the_typedef = objj_allocateTypeDef(\"" + typeDefName + "\");");
|
||||
buffer.concat("{var the_typedef = objj_allocateTypeDef(\"" + typeDefName + "\");", node);
|
||||
|
||||
typeDef = new TypeDef(typeDefName);
|
||||
compiler.typeDefs[typeDefName] = typeDef;
|
||||
|
||||
@@ -115,3 +115,24 @@ if (!Array.prototype.indexOf)
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
// ECMAScript 6 has added this. It is copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
if (!String.prototype.startsWith) {
|
||||
String.prototype.startsWith = function(searchString, position){
|
||||
position = position || 0;
|
||||
return this.substr(position, searchString.length) === searchString;
|
||||
};
|
||||
}
|
||||
|
||||
// ECMAScript 6 has added this. It is copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
|
||||
if (!String.prototype.endsWith) {
|
||||
String.prototype.endsWith = function(searchString, position) {
|
||||
var subjectString = this.toString();
|
||||
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
|
||||
position = subjectString.length;
|
||||
}
|
||||
position -= searchString.length;
|
||||
var lastIndex = subjectString.indexOf(searchString, position);
|
||||
return lastIndex !== -1 && lastIndex === position;
|
||||
};
|
||||
};
|
||||
@@ -1011,4 +1011,4 @@ Preprocessor.prototype.error_message = function(errorMessage)
|
||||
return errorMessage + " <Context File: "+ this._URL +
|
||||
(this._currentClass ? " Class: "+this._currentClass : "") +
|
||||
(this._currentSelector ? " Method: "+this._currentSelector : "") +">";
|
||||
}
|
||||
};
|
||||
|
||||
+17
-1
@@ -646,11 +646,15 @@ GLOBAL(objj_allocateClassPair) = function(/*Class*/ superclass, /*String*/ aName
|
||||
classObject.name = aName;
|
||||
classObject.info = CLS_CLASS;
|
||||
classObject._UID = objj_generateObjectUID();
|
||||
// It needs initialize
|
||||
classObject.init = true;
|
||||
|
||||
metaClassObject.isa = rootClassObject.isa;
|
||||
metaClassObject.name = aName;
|
||||
metaClassObject.info = CLS_META;
|
||||
metaClassObject._UID = objj_generateObjectUID();
|
||||
// It needs initialize
|
||||
metaClassObject.init = true;
|
||||
|
||||
return classObject;
|
||||
}
|
||||
@@ -837,7 +841,16 @@ GLOBAL(objj_msgSend) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
|
||||
var isa = aReceiver.isa;
|
||||
|
||||
CLASS_GET_METHOD_IMPLEMENTATION(var implementation, isa, aSelector);
|
||||
// Here we should do the following line: CLASS_GET_METHOD_IMPLEMENTATION(var implementation, isa, aSelector);
|
||||
// But set the 'init' attribute to 'true' when register the class pair and just check for that here is around 20% faster depending
|
||||
// on environment. The '_class_initialize' function sets the 'init' attribute to 'false' when the class is initialized
|
||||
|
||||
if (isa.init)
|
||||
_class_initialize(isa);
|
||||
|
||||
var method = isa.method_dtable[aSelector];
|
||||
|
||||
var implementation = method ? method.method_imp : _objj_forward;
|
||||
|
||||
#ifdef MAXIMUM_RECURSION_CHECKS
|
||||
if (__objj_msgSend__StackDepth++ > MAXIMUM_RECURSION_DEPTH)
|
||||
@@ -851,6 +864,9 @@ GLOBAL(objj_msgSend) = function(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
case 2: return implementation(aReceiver, aSelector);
|
||||
case 3: return implementation(aReceiver, aSelector, arguments[2]);
|
||||
case 4: return implementation(aReceiver, aSelector, arguments[2], arguments[3]);
|
||||
case 5: return implementation(aReceiver, aSelector, arguments[2], arguments[3], arguments[4]);
|
||||
case 6: return implementation(aReceiver, aSelector, arguments[2], arguments[3], arguments[4], arguments[5]);
|
||||
case 7: return implementation(aReceiver, aSelector, arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
|
||||
}
|
||||
|
||||
return implementation.apply(aReceiver, arguments);
|
||||
|
||||
@@ -197,6 +197,27 @@ StaticResource.prototype.resourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*
|
||||
return StaticResource.resourceAtURL(new CFURL(aURL, this.URL()), resolveAsDirectoriesIfNecessary);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Returns an object with all the resources. Can not be directories.
|
||||
*/
|
||||
StaticResource.resolveResourcesAtURLs = function(/*Array of CFURL|String*/ URLs, /*Function*/ aCallback)
|
||||
{
|
||||
var count = URLs.length,
|
||||
allResources = {};
|
||||
|
||||
for (var i = 0, size = count; i < size; i++)
|
||||
{
|
||||
var url = URLs[i];
|
||||
|
||||
StaticResource.resolveResourceAtURL(url, NO, function(aResource) {
|
||||
allResources[url] = aResource;
|
||||
|
||||
if (--count === 0)
|
||||
aCallback(allResources);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
StaticResource.resolveResourceAtURL = function(/*CFURL|String*/ aURL, /*BOOL*/ isDirectory, /*Function*/ aCallback, /*Dictionary*/ aFilenameTranslateDictionary)
|
||||
{
|
||||
aURL = makeAbsoluteURL(aURL).absoluteURL();
|
||||
|
||||
+212
-72
@@ -26,10 +26,6 @@
|
||||
// [dammit]: acorn_loose.js
|
||||
// [walk]: util/walk.js
|
||||
|
||||
if (typeof exports != "undefined" && !exports.acorn) {
|
||||
exports.acorn = {};
|
||||
exports.acorn.walk = {};
|
||||
}
|
||||
|
||||
(function(exports, walk) {
|
||||
"use strict";
|
||||
@@ -134,7 +130,14 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// #if macro1
|
||||
// #else
|
||||
// #endif
|
||||
// etc...
|
||||
preprocess: true,
|
||||
// Preprocess 'get include file' function. It should return an object with two attributes
|
||||
// 'include': a string with the file to be included
|
||||
// 'sourceFile': is optional and should be a string with the filename. It will
|
||||
// be included in the locations property as 'source'
|
||||
// Return null if file can't be found. The parser will raise an exception
|
||||
preprocessGetIncludeFile: defaultGetIncludeFile,
|
||||
// Preprocess add macro function
|
||||
preprocessAddMacro: defaultAddMacro,
|
||||
// Preprocess get macro function
|
||||
@@ -150,7 +153,12 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
macros: null,
|
||||
// Turn off lineNoInErrorMessage to exclude line number in error messages
|
||||
// Needs to be on to run test cases
|
||||
lineNoInErrorMessage: true
|
||||
lineNoInErrorMessage: true,
|
||||
// Array of files to parse before parsing the main file. Each item is an
|
||||
// object containing the properties 'include' and 'sourceFile'. 'include'
|
||||
// has the content from the file and 'sourceFile' has the file path.
|
||||
// The preprocess options must be turn on for this.
|
||||
preIncludeFiles: null
|
||||
};
|
||||
|
||||
function setOptions(opts) {
|
||||
@@ -166,11 +174,18 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
var macrosMakeBuiltin = function(name, macro, endPos) {return new Macro(name, macro, null, endPos - name.length)}
|
||||
|
||||
var macrosBuiltinMacros = {
|
||||
__OBJJ__: function() {return macrosMakeBuiltin("__OBJJ__", options.objj ? "1" : null, tokPos)},
|
||||
__BROWSER__: function() {return macrosMakeBuiltin("__BROWSER__", typeof(window) !== "undefined" ? "1" : null, tokPos)},
|
||||
__LINE__: function() {return macrosMakeBuiltin("__LINE__", String(options.locations ? tokCurLine : getLineInfo(input, tokPos).line), tokPos)},
|
||||
__OBJJ__: function() {return macrosMakeBuiltin("__OBJJ__", options.objj ? "1" : null, tokPos)}
|
||||
}
|
||||
|
||||
macrosBuiltinMacros["__" + "BROWSER" + "__"] = function() {return macrosMakeBuiltin("__BROWSER__", typeof(window) !== "undefined" ? "1" : null, tokPos)};
|
||||
macrosBuiltinMacros["__" + "LINE" + "__"] = function() {return macrosMakeBuiltin("__LINE__", String(options.locations ? tokCurLine : getLineInfo(input, tokPos).line), tokPos)};
|
||||
macrosBuiltinMacros["__" + "DATE" + "__"] = function() {var date, day; return macrosMakeBuiltin("__DATE__", (date = new Date(), day = String(date.getDate()), ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getMonth()] + (day.length > 1 ? " " : " ") + day + " " + date.getFullYear()), tokPos)};
|
||||
macrosBuiltinMacros["__" + "TIME" + "__"] = function() {var date; return macrosMakeBuiltin("__TIME__", (date = new Date(), ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2) + ":" + ("0" + date.getSeconds()).slice(-2)), tokPos)};
|
||||
|
||||
function defaultGetIncludeFile(filename) {
|
||||
return {include: "#define FOO(x) x\n", sourceFile: filename};
|
||||
}
|
||||
|
||||
function defaultAddMacro(macro) {
|
||||
macros[macro.identifier] = macro;
|
||||
macrosIsPredicate = null;
|
||||
@@ -292,7 +307,19 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// tokMacroOffset is the offset to the current macro for the current token
|
||||
// tokPosMacroOffset is the offset to the current macro for the current tokPos
|
||||
|
||||
var tokFirstStart, tokStart, tokEnd, tokMacroOffset, tokPosMacroOffset, lastTokMacroOffset;
|
||||
var tokFirstStart, firstTokEnd, tokStart, tokEnd, tokMacroOffset, tokPosMacroOffset, lastTokMacroOffset;
|
||||
|
||||
// This is the end position for the last token in the current `input` buffer. Both regular and preprocess
|
||||
// tokens count. It is '0' when entering a new buffer. It is used to determinate if a preprocess (#if) token
|
||||
// is at the begining of a line
|
||||
|
||||
var localLastEnd;
|
||||
|
||||
// Is null except when a macro has ended and then contains the position of the last position in the tokens macro.
|
||||
// `lastEndOfFile` contains this value for the last token. It is used to allow a semicolon to be inserted at the
|
||||
// end of a macro. You can say an end of file is equivalent to a new line.
|
||||
|
||||
var firstEndOfFile, lastEndOfFile;
|
||||
|
||||
// When `options.locations` is true, these hold objects
|
||||
// containing the tokens start and end line/column pairs.
|
||||
@@ -337,7 +364,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// Same as input but for the current token. If options.preprocess is used
|
||||
// this can differ due to macros.
|
||||
|
||||
var tokInput, preTokInput, tokFirstInput;
|
||||
var tokInput, preTokInput, lastEndInput;
|
||||
|
||||
// These store the position of the previous token, which is useful
|
||||
// when finishing a node and assigning its `end` position.
|
||||
@@ -369,6 +396,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
var preprocessParameterScope;
|
||||
var preTokParameterScope;
|
||||
var preprocessOverrideTokEndLoc;
|
||||
var preprocessDontConcatenate; // Don't concatenate tokens when finishing preprocess tokens
|
||||
|
||||
// True if we are concatenating two tokens. This is needed to handle when the second part is an empty macro
|
||||
// This is also used when stingifying tokens to get an empty macro
|
||||
@@ -492,6 +520,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
var _preWarning = {keyword: "warning"};
|
||||
var _preprocessParamItem = {type: "preprocessParamItem"}
|
||||
var _preprocessSkipLine = {type: "skipLine"}
|
||||
var _preInclude = {keyword: "include"};
|
||||
|
||||
// Map keyword names to token types.
|
||||
|
||||
@@ -523,7 +552,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
|
||||
var keywordTypesPreprocessor = {"define": _preDefine, "pragma": _prePragma, "ifdef": _preIfdef, "ifndef": _preIfndef,
|
||||
"undef": _preUndef, "if": _preIf, "endif": _preEndif, "else": _preElse, "elif": _preElseIf,
|
||||
"defined": _preDefined, "warning": _preWarning, "error": _preError};
|
||||
"defined": _preDefined, "warning": _preWarning, "error": _preError, "include": _preInclude};
|
||||
|
||||
// Punctuation token types. Again, the `type` property is purely for debugging.
|
||||
|
||||
@@ -646,7 +675,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
|
||||
// The preprocessor keywords.
|
||||
|
||||
var isKeywordPreprocessor = makePredicate("define undef pragma if ifdef ifndef else elif endif defined error warning");
|
||||
var isKeywordPreprocessor = makePredicate("define undef pragma if ifdef ifndef else elif endif defined error warning include");
|
||||
|
||||
// ## Character categories
|
||||
|
||||
@@ -752,6 +781,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
preprocessStack = [];
|
||||
preprocessStackLastItem = null;
|
||||
preprocessOnlyTransformArgumentsForLastToken = null;
|
||||
preprocessDontConcatenate = false;
|
||||
preNotSkipping = true;
|
||||
preConcatenating = false;
|
||||
preIfLevel = [];
|
||||
@@ -764,15 +794,15 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
|
||||
function finishToken(type, val, overrideTokEnd) {
|
||||
if (overrideTokEnd) {
|
||||
tokEnd = overrideTokEnd;
|
||||
firstTokEnd = tokEnd = overrideTokEnd;
|
||||
if (options.locations) tokEndLoc = preprocessOverrideTokLoc;
|
||||
} else {
|
||||
tokEnd = tokPos;
|
||||
firstTokEnd = tokEnd = tokPos;
|
||||
if (options.locations) tokEndLoc = new line_loc_t;
|
||||
}
|
||||
tokType = type;
|
||||
skipSpace();
|
||||
if (options.preprocess && input.charCodeAt(tokPos) === 35 && input.charCodeAt(tokPos + 1) === 35) { // '##'
|
||||
var ch = skipSpace();
|
||||
if (ch === 35 && options.preprocess && input.charCodeAt(tokPos + 1) === 35) { // '##'
|
||||
var val1 = val != null ? val : type.keyword || type.type;
|
||||
tokPos += 2;
|
||||
if (val1 != null) {
|
||||
@@ -874,21 +904,26 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// will store all skipped comments in `tokComments`. If
|
||||
// `options.trackSpaces` is on, will store the last skipped spaces in
|
||||
// `tokSpaces`.
|
||||
// Returns the char code of the first none whitespace or comment
|
||||
|
||||
function skipSpace() {
|
||||
tokComments = null;
|
||||
tokSpaces = null;
|
||||
onlySkipSpace();
|
||||
return onlySkipSpace();
|
||||
}
|
||||
|
||||
// Returns the char code of the first none whitespace or comment
|
||||
|
||||
function onlySkipSpace(dontSkipEOL, dontSkipMacroBoundary, dontSkipComments) {
|
||||
var spaceStart = tokPos,
|
||||
lastIsNewlinePos;
|
||||
lastIsNewlinePos,
|
||||
ch;
|
||||
for(;;) {
|
||||
var ch = input.charCodeAt(tokPos);
|
||||
ch = input.charCodeAt(tokPos);
|
||||
if (ch === 32) { // ' '
|
||||
++tokPos;
|
||||
} else if (ch === 13 && !dontSkipEOL) {
|
||||
} else if (ch === 13) {
|
||||
if (dontSkipEOL) break;
|
||||
lastIsNewlinePos = tokPos;
|
||||
++tokPos;
|
||||
var next = input.charCodeAt(tokPos);
|
||||
@@ -899,7 +934,8 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
++tokCurLine;
|
||||
tokLineStart = tokPos;
|
||||
}
|
||||
} else if (ch === 10 && !dontSkipEOL) {
|
||||
} else if (ch === 10) {
|
||||
if (dontSkipEOL) break;
|
||||
lastIsNewlinePos = tokPos;
|
||||
++tokPos;
|
||||
if (options.locations) {
|
||||
@@ -908,7 +944,8 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
}
|
||||
} else if (ch === 9) {
|
||||
++tokPos;
|
||||
} else if (ch === 47 && !dontSkipComments) { // '/'
|
||||
} else if (ch === 47) { // '/'
|
||||
if (dontSkipComments) break;
|
||||
var next = input.charCodeAt(tokPos+1);
|
||||
if (next === 42) { // '*'
|
||||
if (options.trackSpaces)
|
||||
@@ -927,27 +964,33 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
if (options.preprocess) {
|
||||
if (dontSkipMacroBoundary) return true;
|
||||
if (!preprocessStack.length) break;
|
||||
// If this is the first end of file after the token save to position to allow a semicolon to be inserted
|
||||
// the end of file, if needed.
|
||||
if (firstEndOfFile == null) firstEndOfFile = tokPos;
|
||||
// If we are at the end of the input inside a macro continue at last position
|
||||
var lastItem = preprocessStack.pop();
|
||||
var saveInputForPrint = input;
|
||||
var saveSourceFileForPrint = sourceFile;
|
||||
tokPos = lastItem.end;
|
||||
input = lastItem.input;
|
||||
inputLen = lastItem.inputLen;
|
||||
tokCurLine = lastItem.currentLine;
|
||||
tokLineStart = lastItem.currentLineStart;
|
||||
/*tokStart = *///tokFirstStart = lastItem.tokStart;
|
||||
//lastEnd = lastItem.lastEnd;
|
||||
//lastStart = lastItem.lastStart;
|
||||
preprocessOnlyTransformArgumentsForLastToken = lastItem.onlyTransformArgumentsForLastToken;
|
||||
preprocessParameterScope = lastItem.parameterScope;
|
||||
tokPosMacroOffset = lastItem.macroOffset;
|
||||
sourceFile = lastItem.sourceFile;
|
||||
firstTokEnd = lastItem.lastEnd;
|
||||
|
||||
// Set the last item
|
||||
var lastIndex = preprocessStack.length;
|
||||
preprocessStackLastItem = lastIndex ? preprocessStack[lastIndex - 1] : null;
|
||||
onlySkipSpace(dontSkipEOL);
|
||||
return onlySkipSpace(dontSkipEOL);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (ch === 92 && options.preprocess) { // '\'
|
||||
} else if (ch === 92) { // '\'
|
||||
if (!options.preprocess) break;
|
||||
// Check if we have an escaped newline. We are using a relaxed treatment of escaped newlines like gcc.
|
||||
// We allow spaces, horizontal and vertical tabs, and form feeds between the backslash and the subsequent newline
|
||||
var pos = tokPos + 1;
|
||||
@@ -969,6 +1012,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
// ### Token reading
|
||||
@@ -1028,7 +1072,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
}
|
||||
|
||||
function readToken_lt_gt(code, finisher) { // '<>'
|
||||
if (tokType === _import && options.objj && code === 60) { // '<'
|
||||
if (code === 60 && (tokType === _import || preTokType === _preInclude) && options.objj) { // '<'
|
||||
for (var start = tokPos + 1;;) {
|
||||
var ch = input.charCodeAt(++tokPos);
|
||||
if (ch === 62) // '>'
|
||||
@@ -1216,6 +1260,30 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
raise(start, "Error: " + String(preprocessEvalExpression(expr)));
|
||||
break;
|
||||
|
||||
case _preInclude:
|
||||
if (!preNotSkipping) {
|
||||
return finisher(_preInclude);
|
||||
}
|
||||
preprocessReadToken();
|
||||
if (preTokType === _string)
|
||||
var localfilepath = true;
|
||||
else if (preTokType ===_filename)
|
||||
var localfilepath = false;
|
||||
else
|
||||
raise(preTokStart, "Expected \"FILENAME\" or <FILENAME>: " + (preTokType.keyword || preTokType.type));
|
||||
|
||||
var theFileName = preTokVal;
|
||||
var includeDict = options.preprocessGetIncludeFile(preTokVal, localfilepath) || raise(preTokStart, "'" + theFileName + "' file not found");
|
||||
var includeString = includeDict.include;
|
||||
var includeMacro = new Macro(null, includeString, null, 0, false, null, false, null, includeDict.sourceFile);
|
||||
preprocessFinishToken(_preprocess, null, null, true); // skipEOL
|
||||
pushMacroToStack(includeMacro, includeMacro.macro, tokPosMacroOffset, null, null, tokPos, null, true); // isIncludeFile
|
||||
skipSpace();
|
||||
readToken(null, null, true); // Stealth
|
||||
return;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if (preprocessStackLastItem) {
|
||||
// If the current macro has parameters check if this word is one of them and should be stringifyed
|
||||
@@ -1240,14 +1308,18 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
else
|
||||
tokSpaces = ["\n"];
|
||||
}
|
||||
preprocessFinishToken(_preprocess, null, null, true); // skipEOL
|
||||
return readToken();
|
||||
preprocessFinishToken(preTokType, null, null, true); // skipEOL
|
||||
return next(true) // Stealth
|
||||
}
|
||||
|
||||
function preprocessParseDefine() {
|
||||
preprocessIsParsingPreprocess = true;
|
||||
preprocessReadToken();
|
||||
var macroIdentifierEnd = preTokEnd;
|
||||
|
||||
// We don't want to concatenate tokens when creating macros
|
||||
preprocessDontConcatenate = true;
|
||||
|
||||
var macroIdentifier = preprocessGetIdent();
|
||||
// '(' Must follow directly after identifier to be a valid macro with parameters
|
||||
if (input.charCodeAt(macroIdentifierEnd) === 40) { // '('
|
||||
@@ -1267,7 +1339,8 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
while(preTokType !== _eol && preTokType !== _eof)
|
||||
preprocessReadToken();
|
||||
|
||||
var macroString = input.slice(start, preTokStart);
|
||||
preprocessDontConcatenate = false;
|
||||
var macroString = preTokInput.slice(start, preTokStart);
|
||||
macroString = macroString.replace(/\\/g, " ");
|
||||
// If variadic get the last parameter for the variadic parameter name
|
||||
options.preprocessAddMacro(new Macro(macroIdentifier, macroString, parameters, start, false, null, variadic && parameters[parameters.length - 1], positionOffset));
|
||||
@@ -1436,8 +1509,8 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
}
|
||||
// Check if it is the first token on the line
|
||||
lineBreak.lastIndex = 0;
|
||||
var match = lineBreak.exec(input.slice(lastEnd, tokPos));
|
||||
if (lastEnd !== 0 && lastEnd !== tokPos && !match) {
|
||||
var match = lineBreak.exec(input.slice(localLastEnd, tokPos));
|
||||
if (lastEnd !== 0 && lastEnd !== tokPos && !match && ((preprocessStackLastItem && !preprocessStackLastItem.isIncludeFile) || tokPos !== 0)) {
|
||||
if (preprocessStackLastItem) {
|
||||
// Stringify next token
|
||||
return preprocessStringify();
|
||||
@@ -1541,10 +1614,12 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// Returns true if it stops at a line break.
|
||||
|
||||
function preprocessSkipSpace(skipComments, skipEOL) {
|
||||
onlySkipSpace(!skipEOL);
|
||||
lineBreak.lastIndex = 0;
|
||||
var match = lineBreak.exec(input.slice(tokPos, tokPos + 2));
|
||||
return match && match.index === 0;
|
||||
var ch = onlySkipSpace(!skipEOL);
|
||||
// Can't see that this line break test is used anymore
|
||||
//lineBreak.lastIndex = 0;
|
||||
//var match = lineBreak.exec(input.slice(tokPos, tokPos + 2));
|
||||
//return (match && match.index === 0);
|
||||
return ch;
|
||||
}
|
||||
|
||||
function preprocessSkipToElseOrEndif(skipElse) {
|
||||
@@ -1586,7 +1661,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
|
||||
// preprocessToken is used to cancel preNotSkipping when calling from readToken_preprocess.
|
||||
// FIXME: Refactor to not use this parameter preprocessToken. It is kind of confusing and it should be possible to do in another way
|
||||
function preprocessReadToken(skipComments, preprocessToken, processMacros) {
|
||||
function preprocessReadToken(skipComments, preprocessToken, processMacros, onlyTransformMacroArguments) {
|
||||
preTokStart = tokPos;
|
||||
preTokInput = input;
|
||||
preTokParameterScope = preprocessParameterScope;
|
||||
@@ -1629,32 +1704,67 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
}
|
||||
}
|
||||
|
||||
function preprocessReadWord(processMacros) {
|
||||
function preprocessReadWord(processMacros, onlyTransformMacroArguments) {
|
||||
var word = readWord1();
|
||||
var type = _name;
|
||||
if (processMacros && options.preprocess) {
|
||||
var readMacroWordReturn = readMacroWord(word, preprocessNext);
|
||||
var readMacroWordReturn = readMacroWord(word, preprocessNext, onlyTransformMacroArguments);
|
||||
if (readMacroWordReturn === true)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!containsEsc && isKeywordPreprocessor(word)) type = keywordTypesPreprocessor[word];
|
||||
preprocessFinishToken(type, word, readMacroWordReturn); // If readMacroWord returns anything except 'true' it is the real tokEndPos
|
||||
preprocessFinishToken(type, word, readMacroWordReturn, false, processMacros); // If readMacroWord returns anything except 'true' it is the real tokEndPos
|
||||
}
|
||||
|
||||
function preprocessFinishToken(type, val, overrideTokEnd, skipEOL) {
|
||||
function preprocessFinishToken(type, val, overrideTokEnd, skipEOL, processMacros) {
|
||||
preTokType = type;
|
||||
preTokVal = val;
|
||||
preTokEnd = overrideTokEnd || tokPos;
|
||||
if (type !== _eol) firstTokEnd = preTokEnd;
|
||||
//tokRegexpAllowed = type.beforeExpr;
|
||||
preprocessSkipSpace(false, skipEOL); // Dont skip comments
|
||||
var ch = preprocessSkipSpace(false, skipEOL); // Dont skip comments
|
||||
if (ch === 35 && options.preprocess && !preprocessDontConcatenate && input.charCodeAt(tokPos + 1) === 35) { // '##'
|
||||
var val1 = val != null ? val : type.keyword || type.type;
|
||||
tokPos += 2;
|
||||
if (val1 != null) {
|
||||
// Save current line and current line start. This is needed when option.locations is true
|
||||
var positionOffset = options.locations && new PositionOffset(tokCurLine, tokLineStart);
|
||||
// Save positions on first token to get start and end correct on node if cancatenated token is invalid
|
||||
var saveTokInput = tokInput, saveTokEnd = preTokEnd, saveTokStart = preTokStart, start = preTokStart + tokMacroOffset, variadicName = preprocessStackLastItem && preprocessStackLastItem.macro && preprocessStackLastItem.macro.variadicName;
|
||||
skipSpace();
|
||||
if (variadicName && variadicName === input.slice(tokPos, tokPos + variadicName.length)) var isVariadic = true;
|
||||
preConcatenating = true;
|
||||
preprocessReadToken(null, null, processMacros, 2); // 2 = Don't transform macros only arguments
|
||||
preConcatenating = false;
|
||||
var val2 = preTokVal != null ? preTokVal : preTokType.keyword || preTokType.type;
|
||||
if (val2 != null) {
|
||||
// Skip token if it is a ',' concatenated with an empty variadic parameter
|
||||
if (isVariadic && val1 === "," && val2 === "") return preprocessReadToken();
|
||||
var concat = "" + val1 + val2, val2TokStart = preTokStart + tokPosMacroOffset;
|
||||
// If the macro defines anything add it to the preprocess input stack
|
||||
var concatMacro = new Macro(null, concat, null, start, false, null, false, positionOffset);
|
||||
var r = readTokenFromMacro(concatMacro, tokPosMacroOffset, preprocessStackLastItem ? preprocessStackLastItem.parameterDict : null, null, tokPos, preprocessNext, null);
|
||||
// Consumed the whole macro in one bite? If not the tokenizer can't create a single token from the two concatenated tokens
|
||||
if (preprocessStackLastItem && preprocessStackLastItem.macro === concatMacro) {
|
||||
// FIXME: Should change this to 'preTokType' and friends
|
||||
preTokType = type;
|
||||
preTokStart = saveTokStart;
|
||||
preTokEnd = saveTokEnd;
|
||||
tokInput = saveTokInput;
|
||||
tokPosMacroOffset = val2TokStart - val1.length; // reset the macro offset to the second token to get start and end correct on node
|
||||
if (!isVariadic) /*raise(tokStart,*/console.log("Warning: pasting formed '" + concat + "', an invalid preprocessing token");
|
||||
} else return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Find out if this is really used?
|
||||
function preprocessFinishTokenSkipComments(type, val) {
|
||||
preTokType = type;
|
||||
preTokVal = val;
|
||||
preTokEnd = tokPos;
|
||||
firstTokEnd = preTokEnd = tokPos;
|
||||
preprocessSkipSpace(true); // 'true' for skip comments
|
||||
}
|
||||
|
||||
@@ -1662,10 +1772,11 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
|
||||
function preprocessNext(stealth, onlyTransformArguments, forceRegexp, processMacros) {
|
||||
if (!stealth) {
|
||||
preLastStart = tokStart;
|
||||
preLastEnd = tokEnd;
|
||||
preLastStart = preTokStart;
|
||||
preLastEnd = preTokEnd;
|
||||
}
|
||||
return preprocessReadToken(false, false, processMacros);
|
||||
localLastEnd = firstTokEnd;
|
||||
return preprocessReadToken(false, false, processMacros, onlyTransformArguments);
|
||||
}
|
||||
|
||||
// Predicate that tests whether the next token is of the given
|
||||
@@ -1682,7 +1793,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// raise with errorMessage or an unexpected token error.
|
||||
|
||||
function preprocessExpect(type, errorMessage, processMacros) {
|
||||
if (preTokType === type) preprocessReadToken(processMacros);
|
||||
if (preTokType === type) preprocessNext(false, undefined, null, processMacros);
|
||||
else raise(preTokStart, errorMessage || "Unexpected token");
|
||||
}
|
||||
|
||||
@@ -1832,7 +1943,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
else tokPos = tokStart + 1;
|
||||
if (!stealth) {
|
||||
tokFirstStart = tokStart;
|
||||
tokFirstInput = input;
|
||||
//tokFirstInput = input;
|
||||
}
|
||||
tokInput = input;
|
||||
tokMacroOffset = tokPosMacroOffset;
|
||||
@@ -2094,7 +2205,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// Lets look ahead to find out if we find a '##' for token concatenate
|
||||
// We don't want to prescan spaces across macro boundary as the macro stack will fall apart
|
||||
// So we do a special prescan if we have to cross a boundary all in the name of speed
|
||||
if (onlySkipSpace(true, true)) { // don't skip EOL and don't skip macro boundary.
|
||||
if (onlySkipSpace(true, true) === true) { // don't skip EOL and don't skip macro boundary.
|
||||
if (preprocessPrescanFor(35, 35)) // Prescan across boundary for '##' as we crossed a boundary
|
||||
onlyTransformArguments = 2;
|
||||
} else if (input.charCodeAt(tokPos) === 35 && input.charCodeAt(tokPos + 1) === 35) { // '##'
|
||||
@@ -2141,7 +2252,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
var pos = tokPos;
|
||||
var loc;
|
||||
if (options.locations) loc = new line_loc_t;
|
||||
if ((onlySkipSpace(true, true) && preprocessPrescanFor(40)) || input.charCodeAt(tokPos) === 40) { // '('
|
||||
if ((onlySkipSpace(true, true) === true && preprocessPrescanFor(40)) || input.charCodeAt(tokPos) === 40) { // '('
|
||||
nextIsParenL = true;
|
||||
} else {
|
||||
// We didn't find a '(' so don't transform to the macro. Return the real tokEndPos so we get correct token end values.
|
||||
@@ -2279,7 +2390,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return scanInput.charCodeAt(scanPos) === first && (second == null || scanInput.charCodeAt(scanPos + 1) === second);
|
||||
return scanInput && scanInput.charCodeAt(scanPos) === first && (second == null || scanInput.charCodeAt(scanPos + 1) === second);
|
||||
}
|
||||
|
||||
// Push macro to stack and start read from it.
|
||||
@@ -2289,20 +2400,10 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// If we are evaluation a macro expresion an empty macro definition means true or '1'
|
||||
if(!macroString && nextFinisher === preprocessNext) macroString = "1";
|
||||
if (macroString) {
|
||||
preprocessStackLastItem = {macro: macro, macroOffset: macroOffset, parameterDict: parameters, /*start: macroStart,*/ end:end, inputLen: inputLen, tokStart: tokStart, onlyTransformArgumentsForLastToken: preprocessOnlyTransformArgumentsForLastToken, currentLine: tokCurLine, currentLineStart: tokLineStart/*, lastStart: lastStart, lastEnd: lastEnd*/};
|
||||
if (parameterScope) preprocessStackLastItem.parameterScope = parameterScope;
|
||||
preprocessStackLastItem.input = input;
|
||||
preprocessStack.push(preprocessStackLastItem);
|
||||
preprocessOnlyTransformArgumentsForLastToken = onlyTransformArguments;
|
||||
input = macroString;
|
||||
inputLen = macroString.length;
|
||||
tokPosMacroOffset = macro.start;
|
||||
tokPos = 0;
|
||||
tokCurLine = 0;
|
||||
tokLineStart = 0;
|
||||
pushMacroToStack(macro, macroString, macroOffset, parameters, parameterScope, end, onlyTransformArguments);
|
||||
} else if (preConcatenating) {
|
||||
// If we are concatenating or stringifying and the macro is empty just make an empty string.
|
||||
finishToken(_name, "");
|
||||
(nextFinisher === next ? finishToken : preprocessFinishToken)(_name, "");
|
||||
return true;
|
||||
}
|
||||
// Now read the next token
|
||||
@@ -2311,6 +2412,27 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Push macro to stack and reset tokPos etc.
|
||||
// macroString is the string from the macro. It is usually 'macro.macro' but the caller can modify it if needed
|
||||
// includeFile is true if the macro should be treated as a regular file. In other words don't stringify words after '#'
|
||||
function pushMacroToStack(macro, macroString, macroOffset, parameters, parameterScope, end, onlyTransformArguments, isIncludeFile) {
|
||||
preprocessStackLastItem = {macro: macro, macroOffset: macroOffset, parameterDict: parameters, /*start: macroStart,*/ end:end, lastEnd: localLastEnd, inputLen: inputLen, tokStart: tokStart, onlyTransformArgumentsForLastToken: preprocessOnlyTransformArgumentsForLastToken, currentLine: tokCurLine, currentLineStart: tokLineStart, sourceFile: sourceFile};
|
||||
if (parameterScope) preprocessStackLastItem.parameterScope = parameterScope;
|
||||
if (isIncludeFile) preprocessStackLastItem.isIncludeFile = isIncludeFile;
|
||||
preprocessStackLastItem.input = input;
|
||||
preprocessStack.push(preprocessStackLastItem);
|
||||
preprocessOnlyTransformArgumentsForLastToken = onlyTransformArguments;
|
||||
input = macroString;
|
||||
inputLen = macroString.length;
|
||||
tokPosMacroOffset = macro.start;
|
||||
tokPos = 0;
|
||||
tokCurLine = 0;
|
||||
tokLineStart = 0;
|
||||
firstTokEnd = 0;
|
||||
localLastEnd = 0;
|
||||
if (macro.sourceFile) sourceFile = macro.sourceFile;
|
||||
}
|
||||
|
||||
// ident is the identifier name for the macro
|
||||
// macro is the macro string
|
||||
// parameters is an array with the parameters for the macro
|
||||
@@ -2319,7 +2441,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// parameterScope is the parameter scope
|
||||
// varadicName is the name of the varadic parameter if it is a varadic macro
|
||||
// locationOffset is the current line that the macro starts at and the position on the line
|
||||
var Macro = exports.Macro = function Macro(ident, macro, parameters, start, isArgument, parameterScope, variadicName, locationOffset) {
|
||||
var Macro = exports.Macro = function Macro(ident, macro, parameters, start, isArgument, parameterScope, variadicName, locationOffset, aSourceFile) {
|
||||
this.identifier = ident;
|
||||
if (macro != null) this.macro = macro;
|
||||
if (parameters) this.parameters = parameters;
|
||||
@@ -2328,6 +2450,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
if (parameterScope) this.parameterScope = parameterScope;
|
||||
if (variadicName) this.variadicName = variadicName;
|
||||
if (locationOffset) this.locationOffset = locationOffset;
|
||||
if (aSourceFile) this.sourceFile = aSourceFile;
|
||||
}
|
||||
|
||||
Macro.prototype.isParameterFunction = function() {
|
||||
@@ -2364,11 +2487,14 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
if (!stealth) {
|
||||
lastStart = tokStart;
|
||||
lastEnd = tokEnd;
|
||||
lastEndInput = tokInput;
|
||||
lastEndOfFile = firstEndOfFile;
|
||||
lastEndLoc = tokEndLoc;
|
||||
lastTokMacroOffset = tokMacroOffset;
|
||||
}
|
||||
nodeMessageSendObjectExpression = null;
|
||||
readToken(forceRegexp, onlyTransformArguments, stealth);
|
||||
localLastEnd = firstTokEnd;
|
||||
firstEndOfFile = nodeMessageSendObjectExpression = null;
|
||||
return readToken(forceRegexp, onlyTransformArguments, stealth);
|
||||
}
|
||||
|
||||
// Enter strict mode. Re-reads the next token to please pedantic
|
||||
@@ -2397,7 +2523,7 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
function node_loc_t() {
|
||||
this.start = tokStartLoc;
|
||||
this.end = null;
|
||||
if (sourceFile !== null) this.source = sourceFile;
|
||||
if (sourceFile != null) this.source = sourceFile;
|
||||
}
|
||||
|
||||
function startNode() {
|
||||
@@ -2508,9 +2634,10 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// Test whether a semicolon can be inserted at the current position.
|
||||
|
||||
function canInsertSemicolon() {
|
||||
//if (lastEnd !== localLastEnd) print("lastEnd: " + lastEnd + ", localLastEnd: " + localLastEnd);
|
||||
return !options.strictSemicolons &&
|
||||
(tokType === _eof || tokType === _braceR || newline.test(tokFirstInput.slice(lastEnd, tokFirstStart)) ||
|
||||
(nodeMessageSendObjectExpression && options.objj));
|
||||
(tokType === _eof || tokType === _braceR || newline.test(lastEndInput.slice(lastEnd, lastEndOfFile || tokFirstStart)) ||
|
||||
(nodeMessageSendObjectExpression && options.objj) || lastEndOfFile != null);
|
||||
}
|
||||
|
||||
// Consume a semicolon, or, failing that, see if we are allowed to
|
||||
@@ -2550,9 +2677,22 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
// statements, and wraps them in a Program node. Optionally takes a
|
||||
// `program` argument. If present, the statements will be appended
|
||||
// to its body instead of creating a new node.
|
||||
// If there are any pre include files they will be pushed onto the macro stack
|
||||
|
||||
function parseTopLevel(program) {
|
||||
lastStart = lastEnd = tokPos;
|
||||
lastStart = localLastEnd = lastEnd = 0;
|
||||
|
||||
if (options.preprocess) {
|
||||
var preIncludeFiles = options.preIncludeFiles;
|
||||
if (preIncludeFiles && preIncludeFiles.length) for (var i = preIncludeFiles.length - 1; i >= 0; i--) {
|
||||
var preIncludeFile = preIncludeFiles[i];
|
||||
|
||||
var preIncludeMacro = new Macro(null, preIncludeFile.include, null, 0, false, null, false, null, preIncludeFile.sourceFile);
|
||||
pushMacroToStack(preIncludeMacro, preIncludeMacro.macro, 0, null, null, tokPos, null, true); // isIncludeFile
|
||||
skipSpace();
|
||||
}
|
||||
}
|
||||
|
||||
if (options.locations) lastEndLoc = new line_loc_t;
|
||||
inFunction = strict = null;
|
||||
labels = [];
|
||||
@@ -3752,4 +3892,4 @@ if (typeof exports != "undefined" && !exports.acorn) {
|
||||
return finishNode(node, "ObjectiveJType");
|
||||
}
|
||||
|
||||
})(exports.acorn, exports.acorn.walk);
|
||||
})(exports.acorn || (exports.acorn = {}), exports.acorn.walk || (exports.acorn.walk = (typeof acorn !== 'undefined') && acorn.walk) || (exports.acorn.walk = {}));
|
||||
|
||||
@@ -198,4 +198,4 @@ function justify(sign, prefix, string, suffix, width, leftJustify, padZeros)
|
||||
function pad(n, ch)
|
||||
{
|
||||
return Array(MAX(0,n)+1).join(ch);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -256,7 +256,6 @@ function reforkWithPackages()
|
||||
if (additionalPackages().length > 0)
|
||||
{
|
||||
var cmd = serializedENV() + " " + system.args.map(OS.enquote).join(" ");
|
||||
//print("REFORKING: " + cmd);
|
||||
OS.exit(OS.system(cmd));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user