Merge pull request #1509 from ajaxorg/hotfix/build

fix #1508: jshint is broken in build
This commit is contained in:
Lennart Kats 2013-07-09 08:23:07 -07:00
commit 3009163083
8 changed files with 349 additions and 176 deletions

View file

@ -603,7 +603,9 @@ function namespace(ns) {
text = text
.toString()
.replace('var ACE_NAMESPACE = "";', 'var ACE_NAMESPACE = "' + ns +'";')
.replace(/\bdefine\(/g, ns + ".define(");
.replace(/(\.define)|\bdefine\(/g, function(_, a) {
return a || ns + ".define("
});
return text;
};

View file

@ -71,7 +71,7 @@ var IncrementalSearch = require("ace/incremental_search").IncrementalSearch;
var workerModule = require("ace/worker/worker_client");
if (location.href.indexOf("noworker" !== -1)) {
if (location.href.indexOf("noworker") !== -1) {
workerModule.WorkerClient = workerModule.UIWorkerClient;
}

View file

@ -1,5 +1,5 @@
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.6 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* @license RequireJS 2.1.7 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) {
var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.6',
version = '2.1.7',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
@ -1794,6 +1794,19 @@ var requirejs, require, define;
*/
req.onError = defaultOnError;
/**
* Creates the node for the load command. Only used in browser envs.
*/
req.createNode = function (config, moduleName, url) {
var node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
return node;
};
/**
* Does the request to load a module for the browser case.
* Make this a separate function to allow other environments
@ -1808,12 +1821,7 @@ var requirejs, require, define;
node;
if (isBrowser) {
//In the browser so use a script tag
node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
node = req.createNode(config, moduleName, url);
node.setAttribute('data-requirecontext', context.contextName);
node.setAttribute('data-requiremodule', moduleName);

View file

@ -1,4 +1,4 @@
define(function() {
define(function(require, exports, module) {
var require = function (file, cwd) {
var resolved = require.resolve(file, cwd || '/');
var mod = require.modules[resolved];
@ -143,7 +143,7 @@ require.alias = function (from, to) {
var global = typeof window !== 'undefined' ? window : {};
var definedProcess = false;
require.define = function (filename, fn) {
require.def = function (filename, fn) {
if (!definedProcess && require.modules.__browserify_process) {
process = require.modules.__browserify_process();
definedProcess = true;
@ -197,7 +197,7 @@ require.alias = function (from, to) {
})();
require.define("path",function(require,module,exports,__dirname,__filename,process,global) {
require.def("path",function(req,module,exports,__dirname,__filename,process,global) {
function filter (xs, fn) {
var res = [];
for (var i = 0; i < xs.length; i++) {
@ -336,7 +336,7 @@ exports.extname = function(path) {
//@ sourceURL=path
});
require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process,global) {
require.def("__browserify_process",function(req,module,exports,__dirname,__filename,process,global) {
var process = module.exports = {};
process.nextTick = (function () {
@ -379,7 +379,7 @@ process.env = {};
process.argv = [];
process.binding = function (name) {
if (name === 'evals') return (require)('vm')
if (name === 'evals') return (req)('vm')
else throw new Error('No such module. (Possibly not yet loaded)')
};
@ -388,7 +388,7 @@ process.binding = function (name) {
var path;
process.cwd = function () { return cwd };
process.chdir = function (dir) {
if (!path) path = require('path');
if (!path) path = req('path');
cwd = path.resolve(dir, cwd);
};
})();
@ -396,12 +396,12 @@ process.binding = function (name) {
//@ sourceURL=__browserify_process
});
require.define("/node_modules/underscore/package.json",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/node_modules/underscore/package.json",function(req,module,exports,__dirname,__filename,process,global) {
module.exports = {"main":"underscore.js"}
//@ sourceURL=/node_modules/underscore/package.json
});
require.define("/node_modules/underscore/underscore.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/node_modules/underscore/underscore.js",function(req,module,exports,__dirname,__filename,process,global) {
// Underscore.js 1.4.0
// http://underscorejs.org
// (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
@ -1592,7 +1592,7 @@ require.define("/node_modules/underscore/underscore.js",function(require,module,
//@ sourceURL=/node_modules/underscore/underscore.js
});
require.define("events",function(require,module,exports,__dirname,__filename,process,global) {
require.def("events",function(req,module,exports,__dirname,__filename,process,global) {
if (!process.EventEmitter) process.EventEmitter = function () {};
var EventEmitter = exports.EventEmitter = process.EventEmitter;
@ -1609,7 +1609,7 @@ var isArray = typeof Array.isArray === 'function'
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
var defaultMaxListeners = 200;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!this._events) this._events = {};
this._events.maxListeners = n;
@ -1768,7 +1768,7 @@ EventEmitter.prototype.listeners = function(type) {
//@ sourceURL=events
});
require.define("/src/shared/vars.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/shared/vars.js",function(req,module,exports,__dirname,__filename,process,global) {
"use strict";
// Identifiers provided by the ECMAScript standard.
@ -2160,10 +2160,10 @@ exports.yui = {
//@ sourceURL=/src/shared/vars.js
});
require.define("/src/shared/messages.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/shared/messages.js",function(req,module,exports,__dirname,__filename,process,global) {
"use strict";
var _ = require("underscore");
var _ = req("underscore");
var errors = {
// JSHint options
@ -2371,17 +2371,17 @@ _.each(info, function (desc, code) {
//@ sourceURL=/src/shared/messages.js
});
require.define("/src/stable/lex.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/stable/lex.js",function(req,module,exports,__dirname,__filename,process,global) {
/*
* Lexical analysis and token construction.
*/
"use strict";
var _ = require("underscore");
var events = require("events");
var reg = require("./reg.js");
var state = require("./state.js").state;
var _ = req("underscore");
var events = req("events");
var reg = req("./reg.js");
var state = req("./state.js").state;
// Some of these token types are from JavaScript Parser API
// while others are specific to JSHint parser.
@ -3987,7 +3987,7 @@ exports.Lexer = Lexer;
//@ sourceURL=/src/stable/lex.js
});
require.define("/src/stable/reg.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/stable/reg.js",function(req,module,exports,__dirname,__filename,process,global) {
/*
* Regular expressions. Some of these are stupidly long.
*/
@ -4025,7 +4025,7 @@ exports.fallsThrough = /^\s*\/\*\s*falls\sthrough\s*\*\/\s*$/;
//@ sourceURL=/src/stable/reg.js
});
require.define("/src/stable/state.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/stable/state.js",function(req,module,exports,__dirname,__filename,process,global) {
"use strict";
var state = {
@ -4051,7 +4051,7 @@ exports.state = state;
//@ sourceURL=/src/stable/state.js
});
require.define("/src/stable/style.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/stable/style.js",function(req,module,exports,__dirname,__filename,process,global) {
"use strict";
exports.register = function (linter) {
@ -4226,7 +4226,7 @@ exports.register = function (linter) {
//@ sourceURL=/src/stable/style.js
});
require.define("/src/stable/jshint.js",function(require,module,exports,__dirname,__filename,process,global) {
require.def("/src/stable/jshint.js",function(req,module,exports,__dirname,__filename,process,global) {
/*!
* JSHint, by JSHint Community.
*
@ -4259,14 +4259,14 @@ require.define("/src/stable/jshint.js",function(require,module,exports,__dirname
/*jshint quotmark:double */
var _ = require("underscore");
var events = require("events");
var vars = require("../shared/vars.js");
var messages = require("../shared/messages.js");
var Lexer = require("./lex.js").Lexer;
var reg = require("./reg.js");
var state = require("./state.js").state;
var style = require("./style.js");
var _ = req("underscore");
var events = req("events");
var vars = req("../shared/vars.js");
var messages = req("../shared/messages.js");
var Lexer = req("./lex.js").Lexer;
var reg = req("./reg.js");
var state = req("./state.js").state;
var style = req("./style.js");
// We build the application inside a function so that we produce only a single
// global variable. That function will be invoked immediately, and its return
@ -5308,7 +5308,7 @@ var JSHINT = (function () {
nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
nonadjacent(state.tokens.curr, state.tokens.next);
}
if (s === "in" && left.id === "!") {
if (s === "in" && left && left.id === "!") {
warning("W018", left, "!");
}
if (typeof f === "function") {
@ -7888,8 +7888,8 @@ if (typeof exports === "object" && exports) {
//@ sourceURL=/src/stable/jshint.js
});
require("/src/stable/jshint.js");
req("/src/stable/jshint.js");
var jsHint = require("/src/stable/jshint.js");
return function(require, exports, module) {module.exports = jsHint;}
}())
function req() {return require.apply(this, arguments)}
module.exports = req("/src/stable/jshint.js");
});

View file

@ -87,6 +87,15 @@ module.exports = {
assert.equal(error.type, "error");
assert.equal(error.row, 0);
assert.equal(error.column, 4);
},
"test for each": function() {
var worker = new JavaScriptWorker(this.sender);
worker.setValue("for each(var i in x)'");
worker.deferredUpdate.call();
var error = this.sender.events[0][1][0];
assert.equal(error.text, "Expected '(' and instead saw 'each'.");
}
};

View file

@ -2,41 +2,11 @@ define(function(require, exports, module) {
/*global exports:true module:true require:true define:true global:true */
(function (root, name, factory) {
'use strict';
var freeExports = typeof exports === 'object' && exports
// While CommonJS defines `module` as an object, component define it as a
// function
, freeModule = (typeof module === 'object' || typeof module === 'function') &&
module && module.exports === freeExports && module;
// Detect free variable `global`, from Node.js or Browserified code, and use
// it as `root`
var freeGlobal = typeof global === 'object' && global;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)
root = freeGlobal;
// Some AMD build optimizers, like r.js, check for specific condition
// patterns like the following:
if (typeof define === 'function' && define.amd) {
define(['exports'], factory);
}
// check for `exports` after `define` in case a build optimizer adds an
// `exports` object
else if (freeExports && !freeExports.nodeType) {
// in Node.js or RingoJS v0.8.0+
if (freeModule) factory(freeModule.exports);
// in Narwhal or RingoJS v0.7.0-
else factory(freeExports);
}
// in a browser or Rhino
else {
factory((root[name] = {}));
}
factory(exports)
}(this, 'luaparse', function (exports) {
'use strict';
exports.version = '0.0.14';
exports.version = '0.1.4';
var input, options, length;
@ -50,6 +20,12 @@ define(function(require, exports, module) {
// Track identifier scopes by adding an isLocal attribute to each
// identifier-node.
, scope: false
// Store location information on each syntax node as
// `loc: { start: { line, column }, end: { line, column } }`.
, locations: false
// Store the start and end character locations on each syntax node as
// `range: [start, end]`.
, ranges: false
};
// The available tokens expressed as enum flags so they can be checked with
@ -59,6 +35,12 @@ define(function(require, exports, module) {
, NumericLiteral = 16, Punctuator = 32, BooleanLiteral = 64
, NilLiteral = 128, VarargLiteral = 256;
exports.tokenTypes = { EOF: EOF, StringLiteral: StringLiteral
, Keyword: Keyword, Identifier: Identifier, NumericLiteral: NumericLiteral
, Punctuator: Punctuator, BooleanLiteral: BooleanLiteral
, NilLiteral: NilLiteral, VarargLiteral: VarargLiteral
};
// As this parser is a bit different from luas own, the error messages
// will be different in some situations.
@ -321,8 +303,31 @@ define(function(require, exports, module) {
, argument: argument
};
}
, comment: function(value, raw) {
return {
type: 'Comment'
, value: value
, raw: raw
};
}
};
// Wrap up the node object.
function finishNode(node) {
// Pop a `Marker` off the location-array and attach its location data.
if (trackLocations) {
var location = locations.pop();
location.complete();
if (options.locations) node.loc = location.loc;
if (options.ranges) node.range = location.range;
}
return node;
}
// Helpers
// -------
@ -335,6 +340,16 @@ define(function(require, exports, module) {
return -1;
};
// Iterate through an array of objects and return the index of an object
// with a matching property.
function indexOfObject(array, property, element) {
for (var i = 0, length = array.length; i < length; i++) {
if (array[i][property] === element) return i;
}
return -1;
}
// A sprintf implementation using %index (beginning at 1) to input
// arguments in the format string.
//
@ -363,7 +378,7 @@ define(function(require, exports, module) {
, dest = {}
, src, prop;
for (var i = 0, l = args.length; i < l; i++) {
for (var i = 0, length = args.length; i < length; i++) {
src = args[i];
for (prop in src) if (src.hasOwnProperty(prop)) {
dest[prop] = src[prop];
@ -471,6 +486,7 @@ define(function(require, exports, module) {
var index
, token
, previousToken
, lookahead
, comments
, tokenStart
@ -496,14 +512,14 @@ define(function(require, exports, module) {
, range: [index, index]
};
var character = input.charCodeAt(index)
var charCode = input.charCodeAt(index)
, next = input.charCodeAt(index + 1);
// Memorize the range index where the token begins.
tokenStart = index;
if (isIdentifierStart(character)) return scanIdentifierOrKeyword();
if (isIdentifierStart(charCode)) return scanIdentifierOrKeyword();
switch (character) {
switch (charCode) {
case 39: case 34: // '"
return scanStringLiteral();
@ -561,10 +577,10 @@ define(function(require, exports, module) {
function skipWhiteSpace() {
while (index < length) {
var character = input.charCodeAt(index);
if (isWhiteSpace(character)) {
var charCode = input.charCodeAt(index);
if (isWhiteSpace(charCode)) {
index++;
} else if (isLineTerminator(character)) {
} else if (isLineTerminator(charCode)) {
line++;
lineStart = ++index;
} else {
@ -640,20 +656,20 @@ define(function(require, exports, module) {
var delimiter = input.charCodeAt(index++)
, stringStart = index
, string = ''
, character;
, charCode;
while (index < length) {
character = input.charCodeAt(index++);
if (delimiter === character) break;
if (92 === character) { // \
charCode = input.charCodeAt(index++);
if (delimiter === charCode) break;
if (92 === charCode) { // \
string += input.slice(stringStart, index - 1) + readEscapeSequence();
stringStart = index;
}
// EOF or `\n` terminates a string literal. If we haven't found the
// ending delimiter by now, raise an exception.
else if (index >= length || isLineTerminator(character)) {
else if (index >= length || isLineTerminator(charCode)) {
string += input.slice(stringStart, index - 1);
raise({}, errors.unfinishedString, string + String.fromCharCode(character));
raise({}, errors.unfinishedString, string + String.fromCharCode(charCode));
}
}
string += input.slice(stringStart, index - 1);
@ -847,7 +863,9 @@ define(function(require, exports, module) {
var character = input.charAt(index)
, content = ''
, isLong = false
, commentStart = index;
, commentStart = index
, lineStartComment = lineStart
, lineComment = line;
if ('[' === character) {
content = readLongString();
@ -861,15 +879,24 @@ define(function(require, exports, module) {
if (isLineTerminator(input.charCodeAt(index))) break;
index++;
}
content = input.slice(commentStart, index);
if (options.comments) content = input.slice(commentStart, index);
}
if (options.comments) {
comments.push({
type: 'Comment'
, value: content
, raw: input.slice(tokenStart, index)
});
var node = ast.comment(content, input.slice(tokenStart, index));
// `Marker`s depend on tokens available in the parser and as comments are
// intercepted in the lexer all location data is set manually.
if (options.locations) {
node.loc = {
start: { line: lineComment, column: tokenStart - lineStartComment }
, end: { line: line, column: index - lineStart }
};
}
if (options.ranges) {
node.range = [tokenStart, index];
}
comments.push(node);
}
}
@ -935,6 +962,7 @@ define(function(require, exports, module) {
// reading in the new lookahead token.
function next() {
previousToken = token;
token = lookahead;
lookahead = lex();
}
@ -959,31 +987,31 @@ define(function(require, exports, module) {
// ### Validation functions
function isWhiteSpace(character) {
return 9 === character || 32 === character || 0xB === character || 0xC === character;
function isWhiteSpace(charCode) {
return 9 === charCode || 32 === charCode || 0xB === charCode || 0xC === charCode;
}
function isLineTerminator(character) {
return 10 === character || 13 === character;
function isLineTerminator(charCode) {
return 10 === charCode || 13 === charCode;
}
function isDecDigit(character) {
return character >= 48 && character <= 57;
function isDecDigit(charCode) {
return charCode >= 48 && charCode <= 57;
}
function isHexDigit(character) {
return (character >= 48 && character <= 57) || (character >= 97 && character <= 102) || (character >= 65 && character <= 70);
function isHexDigit(charCode) {
return (charCode >= 48 && charCode <= 57) || (charCode >= 97 && charCode <= 102) || (charCode >= 65 && charCode <= 70);
}
// From [Lua 5.2](http://www.lua.org/manual/5.2/manual.html#8.1) onwards
// identifiers cannot use locale-dependet letters.
function isIdentifierStart(character) {
return (character >= 65 && character <= 90) || (character >= 97 && character <= 122) || 95 === character;
function isIdentifierStart(charCode) {
return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode;
}
function isIdentifierPart(character) {
return (character >= 65 && character <= 90) || (character >= 97 && character <= 122) || 95 === character || (character >= 48 && character <= 57);
function isIdentifierPart(charCode) {
return (charCode >= 65 && charCode <= 90) || (charCode >= 97 && charCode <= 122) || 95 === charCode || (charCode >= 48 && charCode <= 57);
}
// [3.1 Lexical Conventions](http://www.lua.org/manual/5.2/manual.html#3.1)
@ -1048,11 +1076,7 @@ define(function(require, exports, module) {
// The current scope index
, scopeDepth
// A list of all global identifier nodes.
, globals
// A list of all global identifiers names used for faster lookup.
// @TODO benchmark, with exposing the globals this entire implementation
// should probably change.
, globalNames;
, globals;
// Create a new scope inheriting all declarations from the previous scope.
function createScope() {
@ -1080,10 +1104,8 @@ define(function(require, exports, module) {
// Attach scope information to node. If the node is global, store it in the
// globals array so we can return the information to the user.
function attachScope(node, isLocal) {
if (!isLocal && -1 === indexOf(globalNames, node.name)) {
globalNames.push(node.name);
if (!isLocal && -1 === indexOfObject(globals, 'name', node.name))
globals.push(node);
}
node.isLocal = isLocal;
}
@ -1093,6 +1115,57 @@ define(function(require, exports, module) {
return (-1 !== indexOf(scopes[scopeDepth], name));
}
// Location tracking
// -----------------
//
// Locations are stored in FILO-array as a `Marker` object consisting of both
// `loc` and `range` data. Once a `Marker` is popped off the list an end
// location is added and the data is attached to a syntax node.
var locations = []
, trackLocations;
function createLocationMarker() {
return new Marker(token);
}
function Marker(token) {
if (options.locations) {
this.loc = {
start: {
line: token.line
, column: token.range[0] - token.lineStart
}
, end: {
line: 0
, column: 0
}
};
}
if (options.ranges) this.range = [token.range[0], 0];
}
// Complete the location data stored in the `Marker` by adding the location
// of the *previous token* as an end location.
Marker.prototype.complete = function() {
if (options.locations) {
this.loc.end.line = previousToken.line;
this.loc.end.column = previousToken.range[1] - previousToken.lineStart;
}
if (options.ranges) {
this.range[1] = previousToken.range[1];
}
};
// Create a new `Marker` and add it to the FILO-array.
function markLocation() {
if (trackLocations) locations.push(createLocationMarker());
}
// Push an arbitrary `Marker` object onto the FILO-array.
function pushLocation(marker) {
if (trackLocations) locations.push(marker);
}
// Parse functions
// ---------------
@ -1103,9 +1176,12 @@ define(function(require, exports, module) {
function parseChunk() {
next();
markLocation();
var body = parseBlock();
if (EOF !== token.type) unexpected(token);
return ast.chunk(body);
// If the body is empty no previousToken exists when finishNode runs.
if (trackLocations && !body.length) previousToken = token;
return finishNode(ast.chunk(body));
}
// A block contains a list of statements with an optional return statement
@ -1144,6 +1220,7 @@ define(function(require, exports, module) {
// | functioncall | ';'
function parseStatement() {
markLocation();
if (Keyword === token.type) {
switch (token.value) {
case 'local': next(); return parseLocalStatement();
@ -1164,6 +1241,9 @@ define(function(require, exports, module) {
if (Punctuator === token.type) {
if (consume('::')) return parseLabelStatement();
}
// Assignments memorizes the location and pushes it manually for wrapper
// nodes. Additionally empty `;` statements should not mark a location.
if (trackLocations) locations.pop();
// When a `;` is encounted, simply eat it without storing it.
if (consume(';')) return;
@ -1185,13 +1265,13 @@ define(function(require, exports, module) {
}
expect('::');
return ast.labelStatement(label);
return finishNode(ast.labelStatement(label));
}
// break ::= 'break'
function parseBreakStatement() {
return ast.breakStatement();
return finishNode(ast.breakStatement());
}
// goto ::= 'goto' Name
@ -1201,7 +1281,7 @@ define(function(require, exports, module) {
, label = parseIdentifier();
if (options.scope) label.isLabel = scopeHasName('::' + name + '::');
return ast.gotoStatement(label);
return finishNode(ast.gotoStatement(label));
}
// do ::= 'do' block 'end'
@ -1209,7 +1289,7 @@ define(function(require, exports, module) {
function parseDoStatement() {
var body = parseBlock();
expect('end');
return ast.doStatement(body);
return finishNode(ast.doStatement(body));
}
// while ::= 'while' exp 'do' block 'end'
@ -1219,7 +1299,7 @@ define(function(require, exports, module) {
expect('do');
var body = parseBlock();
expect('end');
return ast.whileStatement(condition, body);
return finishNode(ast.whileStatement(condition, body));
}
// repeat ::= 'repeat' block 'until' exp
@ -1228,7 +1308,7 @@ define(function(require, exports, module) {
var body = parseBlock();
expect('until');
var condition = parseExpectedExpression();
return ast.repeatStatement(condition, body);
return finishNode(ast.repeatStatement(condition, body));
}
// retstat ::= 'return' [exp {',' exp}] [';']
@ -1245,7 +1325,7 @@ define(function(require, exports, module) {
}
consume(';'); // grammar tells us ; is optional here.
}
return ast.returnStatement(expressions);
return finishNode(ast.returnStatement(expressions));
}
// if ::= 'if' exp 'then' block {elif} ['else' block] 'end'
@ -1254,27 +1334,42 @@ define(function(require, exports, module) {
function parseIfStatement() {
var clauses = []
, condition
, body;
, body
, marker;
// IfClauses begin at the same location as the parent IfStatement.
// It ends at the start of `end`, `else`, or `elseif`.
if (trackLocations) {
marker = locations[locations.length - 1];
locations.push(marker);
}
condition = parseExpectedExpression();
expect('then');
body = parseBlock();
clauses.push(ast.ifClause(condition, body));
clauses.push(finishNode(ast.ifClause(condition, body)));
if (trackLocations) marker = createLocationMarker();
while (consume('elseif')) {
pushLocation(marker);
condition = parseExpectedExpression();
expect('then');
body = parseBlock();
clauses.push(ast.elseifClause(condition, body));
clauses.push(finishNode(ast.elseifClause(condition, body)));
if (trackLocations) marker = createLocationMarker();
}
if (consume('else')) {
// Include the `else` in the location of ElseClause.
if (trackLocations) {
marker = new Marker(previousToken);
locations.push(marker);
}
body = parseBlock();
clauses.push(ast.elseClause(body));
clauses.push(finishNode(ast.elseClause(body)));
}
expect('end');
return ast.ifStatement(clauses);
return finishNode(ast.ifStatement(clauses));
}
// There are two types of for statements, generic and numeric.
@ -1306,7 +1401,7 @@ define(function(require, exports, module) {
body = parseBlock();
expect('end');
return ast.forNumericStatement(variable, start, end, step, body);
return finishNode(ast.forNumericStatement(variable, start, end, step, body));
}
// If not, it's a Generic For Statement
else {
@ -1331,7 +1426,7 @@ define(function(require, exports, module) {
body = parseBlock();
expect('end');
return ast.forGenericStatement(variables, iterators, body);
return finishNode(ast.forGenericStatement(variables, iterators, body));
}
}
@ -1374,7 +1469,7 @@ define(function(require, exports, module) {
}
}
return ast.localStatement(variables, init);
return finishNode(ast.localStatement(variables, init));
}
if (consume('function')) {
name = parseIdentifier();
@ -1398,7 +1493,10 @@ define(function(require, exports, module) {
// Keep a reference to the previous token for better error messages in case
// of invalid statement
var previous = token
, expression = parsePrefixExpression();
, expression, marker;
if (trackLocations) marker = createLocationMarker();
expression = parsePrefixExpression();
if (null == expression) return unexpected(token);
if (',='.indexOf(token.value) >= 0) {
@ -1416,10 +1514,13 @@ define(function(require, exports, module) {
exp = parseExpectedExpression();
init.push(exp);
} while (consume(','));
return ast.assignmentStatement(variables, init);
pushLocation(marker);
return finishNode(ast.assignmentStatement(variables, init));
}
if (isCallExpression(expression)) {
return ast.callStatement(expression);
pushLocation(marker);
return finishNode(ast.callStatement(expression));
}
// The prefix expression was neither part of an assignment or a
// callstatement, however as it was valid it's been consumed, so raise
@ -1434,10 +1535,11 @@ define(function(require, exports, module) {
// Identifier ::= Name
function parseIdentifier() {
markLocation();
var identifier = token.value;
if (Identifier !== token.type) raiseUnexpectedToken('<name>', token);
next();
return ast.identifier(identifier);
return finishNode(ast.identifier(identifier));
}
// Parse the functions parameters and body block. The name should already
@ -1484,7 +1586,7 @@ define(function(require, exports, module) {
expect('end');
isLocal = isLocal || false;
return ast.functionStatement(name, parameters, isLocal, body);
return finishNode(ast.functionStatement(name, parameters, isLocal, body));
}
// Parse the function name as identifiers and member expressions.
@ -1492,20 +1594,25 @@ define(function(require, exports, module) {
// Name {'.' Name} [':' Name]
function parseFunctionName() {
var base = parseIdentifier()
, name;
var base, name, marker;
if (trackLocations) marker = createLocationMarker();
base = parseIdentifier();
if (options.scope) attachScope(base, false);
while (consume('.')) {
pushLocation(marker);
name = parseIdentifier();
if (options.scope) attachScope(name, false);
base = ast.memberExpression(base, '.', name);
base = finishNode(ast.memberExpression(base, '.', name));
}
if (consume(':')) {
pushLocation(marker);
name = parseIdentifier();
if (options.scope) attachScope(name, false);
base = ast.memberExpression(base, ':', name);
base = finishNode(ast.memberExpression(base, ':', name));
}
return base;
@ -1522,23 +1629,27 @@ define(function(require, exports, module) {
, key, value;
while (true) {
markLocation();
if (Punctuator === token.type && consume('[')) {
key = parseExpectedExpression();
expect(']');
expect('=');
value = parseExpectedExpression();
fields.push(ast.tableKey(key, value));
fields.push(finishNode(ast.tableKey(key, value)));
} else if (Identifier === token.type) {
key = parseExpectedExpression();
if (consume('=')) {
value = parseExpectedExpression();
fields.push(ast.tableKeyString(key, value));
fields.push(finishNode(ast.tableKeyString(key, value)));
} else {
fields.push(ast.tableValue(key));
fields.push(finishNode(ast.tableValue(key)));
}
} else {
if (null == (value = parseExpression())) break;
fields.push(ast.tableValue(value));
if (null == (value = parseExpression())) {
locations.pop();
break;
}
fields.push(finishNode(ast.tableValue(value)));
}
if (',;'.indexOf(token.value) >= 0) {
next();
@ -1547,7 +1658,7 @@ define(function(require, exports, module) {
if ('}' === token.value) break;
}
expect('}');
return ast.tableConstructorExpression(fields);
return finishNode(ast.tableConstructorExpression(fields));
}
// Expression parser
@ -1588,23 +1699,23 @@ define(function(require, exports, module) {
// the expensive CompareICStub which took ~8% of the parse time.
function binaryPrecedence(operator) {
var character = operator.charCodeAt(0)
var charCode = operator.charCodeAt(0)
, length = operator.length;
if (1 === length) {
switch (character) {
switch (charCode) {
case 94: return 10; // ^
case 42: case 47: case 37: return 7; // * / %
case 43: case 45: return 6; // + -
case 60: case 62: return 3; // < >
}
} else if (2 === length) {
switch (character) {
switch (charCode) {
case 46: return 5; // ..
case 60: case 62: case 61: case 126: return 3; // <= >= == ~=
case 111: return 1; // or
}
} else if (97 === character && 'and' === operator) return 2;
} else if (97 === charCode && 'and' === operator) return 2;
return 0;
}
@ -1618,16 +1729,19 @@ define(function(require, exports, module) {
// exp ::= (unop exp | primary | prefixexp ) { binop exp }
function parseSubExpression(minPrecedence) {
var operator = token.value;
var operator = token.value
// The left-hand side in binary operations.
var expression;
, expression, marker;
if (trackLocations) marker = createLocationMarker();
// UnaryExpression
if (isUnary(token)) {
markLocation();
next();
var argument = parseSubExpression(8);
if (argument == null) raiseUnexpectedToken('<expression>', token);
expression = ast.unaryExpression(operator, argument);
expression = finishNode(ast.unaryExpression(operator, argument));
}
if (null == expression) {
// PrimaryExpression
@ -1654,7 +1768,10 @@ define(function(require, exports, module) {
next();
var right = parseSubExpression(precedence);
if (null == right) raiseUnexpectedToken('<expression>', token);
expression = ast.binaryExpression(operator, expression, right);
// Push in the marker created before the loop to wrap its entirety.
if (trackLocations) locations.push(marker);
expression = finishNode(ast.binaryExpression(operator, expression, right));
}
return expression;
}
@ -1666,10 +1783,12 @@ define(function(require, exports, module) {
// args ::= '(' [explist] ')' | tableconstructor | String
function parsePrefixExpression() {
var base, name
var base, name, marker
// Keep track of the scope, if a parent is local so are the children.
, isLocal;
if (trackLocations) marker = createLocationMarker();
// The prefix
if (Identifier === token.type) {
name = token.value;
@ -1690,34 +1809,40 @@ define(function(require, exports, module) {
if (Punctuator === token.type) {
switch (token.value) {
case '[':
pushLocation(marker);
next();
expression = parseExpectedExpression();
base = ast.indexExpression(base, expression);
base = finishNode(ast.indexExpression(base, expression));
expect(']');
break;
case '.':
pushLocation(marker);
next();
identifier = parseIdentifier();
// Inherit the scope
if (options.scope) attachScope(identifier, isLocal);
base = ast.memberExpression(base, '.', identifier);
base = finishNode(ast.memberExpression(base, '.', identifier));
break;
case ':':
pushLocation(marker);
next();
identifier = parseIdentifier();
if (options.scope) attachScope(identifier, isLocal);
base = ast.memberExpression(base, ':', identifier);
// Once a : is found, this has to be a callexpression, otherwise
base = finishNode(ast.memberExpression(base, ':', identifier));
// Once a : is found, this has to be a CallExpression, otherwise
// throw an error.
pushLocation(marker);
base = parseCallExpression(base);
break;
case '(': case '{': // args
pushLocation(marker);
base = parseCallExpression(base);
break;
default:
return base;
}
} else if (StringLiteral === token.type) {
pushLocation(marker);
base = parseCallExpression(base);
} else {
break;
@ -1745,15 +1870,16 @@ define(function(require, exports, module) {
}
expect(')');
return ast.callExpression(base, expressions);
return finishNode(ast.callExpression(base, expressions));
case '{':
markLocation();
next();
var table = parseTableConstructor();
return ast.tableCallExpression(base, table);
return finishNode(ast.tableCallExpression(base, table));
}
} else if (StringLiteral === token.type) {
return ast.stringCallExpression(base, parsePrimaryExpression());
return finishNode(ast.stringCallExpression(base, parsePrimaryExpression()));
}
raiseUnexpectedToken('function arguments', token);
@ -1765,17 +1891,24 @@ define(function(require, exports, module) {
function parsePrimaryExpression() {
var literals = StringLiteral | NumericLiteral | BooleanLiteral | NilLiteral | VarargLiteral
, value = token.value
, type = token.type;
, type = token.type
, marker;
if (trackLocations) marker = createLocationMarker();
if (type & literals) {
pushLocation(marker);
var raw = input.slice(token.range[0], token.range[1]);
next();
return ast.literal(type, value, raw);
return finishNode(ast.literal(type, value, raw));
} else if (Keyword === type && 'function' === value) {
pushLocation(marker);
next();
return parseFunctionDeclaration(null);
} else if (consume('{'))
} else if (consume('{')) {
pushLocation(marker);
return parseTableConstructor();
}
}
// Parser
@ -1813,7 +1946,7 @@ define(function(require, exports, module) {
scopes = [[]];
scopeDepth = 0;
globals = [];
globalNames = [];
locations = [];
if (options.comments) comments = [];
if (!options.wait) return end();
@ -1836,12 +1969,17 @@ define(function(require, exports, module) {
if ('undefined' !== typeof _input) write(_input);
length = input.length;
trackLocations = options.locations || options.ranges;
// Initialize with a lookahead token.
lookahead = lex();
var chunk = parseChunk();
if (options.comments) chunk.comments = comments;
if (options.scope) chunk.globals = globals;
if (locations.length > 0)
throw new Error('Location tracking failed. This is most likely a bug in luaparse');
return chunk;
}

View file

@ -12,7 +12,8 @@ window.console = {
error: function() {
var msgs = Array.prototype.slice.call(arguments, 0);
postMessage({type: "log", data: msgs});
}
},
trace: function() {}
};
window.window = window;
window.ace = window;

View file

@ -16,7 +16,13 @@ var deps = [{
}, {
path: "mode/lua/luaparse.js",
url: "https://raw.github.com/oxyc/luaparse/master/luaparse.js",
needsFixup: true
needsFixup: true,
postProcess: function(src) {
return src.replace(
/\(function\s*\(root,\s*name,\s*factory\)\s*{[\s\S]*?}\(this,\s*'luaparse',/,
"(function (root, name, factory) {\n factory(exports)\n}(this, 'luaparse',"
)
}
}];
var download = function(href, callback) {
@ -39,12 +45,12 @@ var download = function(href, callback) {
var getDep = function(dep) {
download(dep.url, function(data) {
if (dep.postProcess)
data = dep.postProcess(data);
if (dep.needsFixup)
data = "define(function(require, exports, module) {\n"
+ data
+ "\n});";
if (dep.postProcess)
data = dep.postProcess(data);
fs.writeFile(rootDir + dep.path, data, "utf-8", function(err){
if (err) throw err;
@ -173,10 +179,19 @@ run("npm install jshint", function() {
/"Expected a conditional expression and instead saw an assignment."/g,
'"Assignment in conditional expression"'
);
jshintDist = 'define(function() {\n'
jshintDist = jshintDist.replace(/\brequire\(["']|\(require,|\(require\)/g, function(r){
return r.replace("require", "req");
}).replace(/\brequire\.define(\(|\s*=)/g, function(d){
return d.replace("define", "def");
});
jshintDist = jshintDist.replace(/var defaultMaxListeners = 10;/, function(a) {return a.replace("10", "200")});
jshintDist = 'define(function(require, exports, module) {\n'
+ jshintDist + '\n'
+ 'var jsHint = require("/src/stable/jshint.js");\n'
+ 'return function(require, exports, module) {module.exports = jsHint;}\n'
+'}())';
+ 'function req() {return require.apply(this, arguments)}\n'
+ 'module.exports = req("/src/stable/jshint.js");\n'
+'});';
fs.writeFileSync(rootDir + "mode/javascript/jshint.js", jshintDist);
});