diff --git a/lib/ace/mode/javascript/jshint.js b/lib/ace/mode/javascript/jshint.js index 5069fbe0..97ee04d2 100644 --- a/lib/ace/mode/javascript/jshint.js +++ b/lib/ace/mode/javascript/jshint.js @@ -152,7 +152,7 @@ define(function(require, exports, module) { /*members "\b", "\t", "\n", "\f", "\r", "!=", "!==", "\"", "%", "(begin)", "(breakage)", "(character)", "(context)", "(error)", "(explicitNewcap)", "(global)", "(identifier)", "(last)", "(lastcharacter)", "(line)", "(loopage)", "(metrics)", - "(name)", "(onevar)", "(params)", "(scope)", "(statement)", "(verb)", "(tokens)", + "(name)", "(onevar)", "(params)", "(scope)", "(statement)", "(verb)", "(tokens)", "(catch)", "*", "+", "++", "-", "--", "\/", "<", "<=", "==", "===", ">", ">=", $, $$, $A, $F, $H, $R, $break, $continue, $w, Abstract, Ajax, __filename, __dirname, ActiveXObject, Array, ArrayBuffer, ArrayBufferView, Audio, @@ -216,13 +216,13 @@ define(function(require, exports, module) { removeEventListener, replace, report, require, reserved, resizeBy, resizeTo, resolvePath, resumeUpdates, respond, rhino, right, runCommand, scroll, scope, screen, scripturl, scrollBy, scrollTo, scrollbar, search, seal, self, send, serialize, sessionStorage, setInterval, setTimeout, - setter, setterToken, shift, slice, smarttabs, sort, spawn, split, statementCount, stack, status, - start, strict, sub, substr, supernew, shadow, supplant, sum, sync, test, toLowerCase, toString, - toUpperCase, toint32, token, tokens, top, trailing, type, typeOf, Uint16Array, Uint32Array, - Uint8Array, undef, undefs, unused, urls, validthis, value, valueOf, var, vars, version, - verifyMaxParametersPerFunction, verifyMaxStatementsPerFunction, verifyMaxComplexityPerFunction, - verifyMaxNestedBlockDepthPerFunction, WebSocket, withstmt, white, window, windows, Worker, worker, - wsh*/ + setter, setterToken, shift, slice, smarttabs, sort, spawn, split, statement, statementCount, stack, + status, start, strict, sub, substr, supernew, shadow, supplant, sum, sync, test, toLowerCase, + toString, toUpperCase, toint32, token, tokens, top, trailing, type, typeOf, Uint16Array, + Uint32Array, Uint8Array, undef, undefs, unused, urls, validthis, value, valueOf, var, vars, + version, verifyMaxParametersPerFunction, verifyMaxStatementsPerFunction, + verifyMaxComplexityPerFunction, verifyMaxNestedBlockDepthPerFunction, WebSocket, withstmt, white, + window, windows, Worker, worker, wsh*/ /*global exports: false */ @@ -795,7 +795,7 @@ var JSHINT = (function () { cx = /[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; // token - tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/(\*(jshint|jslint|members?|global)?|=|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; + tx = /^\s*([(){}\[.,:;'"~\?\]#@]|==?=?|\/=(?!(\S*\/[gim]?))|\/(\*(jshint|jslint|members?|global)?|\/)?|\*[\/=]?|\+(?:=|\++)?|-(?:=|-+)?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|--)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/; // characters in strings that need escapement nx = /[\u0000-\u001f&<"\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/; @@ -1268,6 +1268,7 @@ var JSHINT = (function () { function match(x) { var r = x.exec(s), r1; + if (r) { l = r[0].length; r1 = r[1]; @@ -1313,6 +1314,7 @@ var JSHINT = (function () { character += n; c = String.fromCharCode(i); } + j = 0; unclosedString: for (;;) { while (j >= s.length) { @@ -1330,12 +1332,14 @@ unclosedString: for (;;) { warningAt("Unclosed string.", cl, cf); } } + c = s.charAt(j); if (c === x) { character += 1; s = s.substr(j + 1); return it("(string)", r, x); } + if (c < " ") { if (c === "\n" || c === "\r") { break; @@ -1432,7 +1436,9 @@ unclosedString: for (;;) { if (!s) { return it(nextLine() ? "(endline)" : "(end)", ""); } + t = match(tx); + if (!t) { t = ""; c = ""; @@ -1531,10 +1537,11 @@ unclosedString: for (;;) { break; // / case "/": - if (token.id === "/=") { + if (s.charAt(0) === "=") { errorAt("A regular expression literal can be confused with '/='.", line, from); } + if (prereg) { depth = 0; captures = 0; @@ -1756,6 +1763,7 @@ klass: do { if (c < "0" || c > "9") { warningAt( "Expected a number and instead saw '{a}'.", line, from + l, c); + break; // No reason to continue checking numbers. } l += 1; low = +c; @@ -1828,13 +1836,22 @@ klass: do { } // Define t in the current function in the current scope. + if (type === "exception") { + if (is_own(funct["(context)"], t)) { + if (funct[t] !== true && !option.node) { + warning("Value of '{a}' may be overwritten in IE.", nexttoken, t); + } + } + } + if (is_own(funct, t) && !funct["(global)"]) { if (funct[t] === true) { if (option.latedef) warning("'{a}' was used before it was defined.", nexttoken, t); } else { - if (!option.shadow && type !== "exception") + if (!option.shadow && type !== "exception") { warning("'{a}' is already defined.", nexttoken, t); + } } } @@ -1923,31 +1940,27 @@ loop: for (;;) { checkOption(t.value, t); } - if (t.value === "indent" && (o === "/*jshint" || o === "/*jslint")) { + var numericVals = [ + "maxstatements", + "maxparams", + "maxdepth", + "maxcomplexity", + "maxerr", + "maxlen", + "indent" + ]; + + if (numericVals.indexOf(t.value) > -1 && (o === "/*jshint" || o === "/*jslint")) { b = +v.value; - if (typeof b !== "number" || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); + + if (typeof b !== "number" || !isFinite(b) || b <= 0 || Math.floor(b) !== b) { + error("Expected a small integer and instead saw '{a}'.", v, v.value); } - obj.white = true; - obj.indent = b; - } else if (t.value === "maxerr" && (o === "/*jshint" || o === "/*jslint")) { - b = +v.value; - if (typeof b !== "number" || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxerr = b; - } else if (t.value === "maxlen" && (o === "/*jshint" || o === "/*jslint")) { - b = +v.value; - if (typeof b !== "number" || !isFinite(b) || b <= 0 || - Math.floor(b) !== b) { - error("Expected a small integer and instead saw '{a}'.", - v, v.value); - } - obj.maxlen = b; + + if (t.value === "indent") + obj.white = true; + + obj[t.value] = b; } else if (t.value === "validthis") { if (funct["(global)"]) { error("Option 'validthis' can't be used in a global scope."); @@ -2772,7 +2785,10 @@ loop: for (;;) { d; inblock = ordinary; - if (!ordinary || !option.funcscope) scope = Object.create(scope); + + if (!ordinary || !option.funcscope) + scope = Object.create(scope); + nonadjacent(token, nexttoken); t = nexttoken; @@ -3411,7 +3427,8 @@ loop: for (;;) { } while (nexttoken.id !== "(end)") { while (nexttoken.id === ",") { - warning("Extra comma."); + if (!option.es5) + warning("Extra comma."); advance(","); } if (nexttoken.id === "]") { @@ -3483,16 +3500,16 @@ loop: for (;;) { } - function doFunction(i, statement) { - var f, - oldOption = option, - oldScope = scope; + function doFunction(name, statement) { + var f; + var oldOption = option; + var oldScope = scope; option = Object.create(option); - scope = Object.create(scope); + scope = Object.create(scope); funct = { - "(name)" : i || "\"" + anonname + "\"", + "(name)" : name || "\"" + anonname + "\"", "(line)" : nexttoken.line, "(character)": nexttoken.character, "(context)" : funct, @@ -3503,12 +3520,16 @@ loop: for (;;) { "(statement)": statement, "(tokens)" : {} }; + f = funct; token.funct = funct; + functions.push(funct); - if (i) { - addlabel(i, "function"); + + if (name) { + addlabel(name, "function"); } + funct["(params)"] = functionparams(); funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]); @@ -3522,6 +3543,7 @@ loop: for (;;) { funct["(last)"] = token.line; funct["(lastcharacter)"] = token.character; funct = funct["(context)"]; + return f; } @@ -3829,7 +3851,7 @@ loop: for (;;) { adjacent(token, nexttoken); addlabel(i, "unction", token); - doFunction(i, true); + doFunction(i, { statement: true }); if (nexttoken.id === "(" && nexttoken.line === token.line) { error( "Function declarations are not invocable. Wrap the whole function invocation in parens."); @@ -3880,29 +3902,65 @@ loop: for (;;) { }); blockstmt("try", function () { - var b, e, s; + var b; + + function doCatch() { + var oldScope = scope; + var e; - block(false); - if (nexttoken.id === "catch") { - increaseComplexityCount(); advance("catch"); nonadjacent(token, nexttoken); advance("("); - s = scope; - scope = Object.create(s); + + scope = Object.create(oldScope); + e = nexttoken.value; if (nexttoken.type !== "(identifier)") { - warning("Expected an identifier and instead saw '{a}'.", - nexttoken, e); - } else { - addlabel(e, "exception"); + e = null; + warning("Expected an identifier and instead saw '{a}'.", nexttoken, e); } + advance(); advance(")"); + + funct = { + "(name)" : "(catch)", + "(line)" : nexttoken.line, + "(character)": nexttoken.character, + "(context)" : funct, + "(breakage)" : funct["(breakage)"], + "(loopage)" : funct["(loopage)"], + "(scope)" : scope, + "(statement)": false, + "(metrics)" : createMetrics(nexttoken), + "(catch)" : true, + "(tokens)" : {} + }; + + if (e) { + addlabel(e, "exception"); + } + + token.funct = funct; + functions.push(funct); + block(false); - b = true; - scope = s; + + scope = oldScope; + + funct["(last)"] = token.line; + funct["(lastcharacter)"] = token.character; + funct = funct["(context)"]; } + + block(false); + + if (nexttoken.id === "catch") { + increaseComplexityCount(); + doCatch(); + b = true; + } + if (nexttoken.id === "finally") { advance("finally"); block(false); @@ -3911,6 +3969,7 @@ loop: for (;;) { error("Expected '{a}' and instead saw '{b}'.", nexttoken, "catch", nexttoken.value); } + return this; }); diff --git a/tool/update_deps.js b/tool/update_deps.js index 0ad38e94..91630a50 100644 --- a/tool/update_deps.js +++ b/tool/update_deps.js @@ -6,7 +6,7 @@ var https = require("https") var rootDir = __dirname + "/../lib/ace/" var deps = [{ - path: "worker/jshint.js", + path: "mode/javascript/jshint.js", url: "https://raw.github.com/jshint/jshint/master/jshint.js", needsFixup: true, postProcess: function(t) {