Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: jshint/jshint
base: f2843c5294
...
head fork: jshint/jshint
compare: e32ae7e3ca
Checking mergeability… Don't worry, you can still create the pull request.
  • 5 commits
  • 8 files changed
  • 1 commit comment
  • 2 contributors
Commits on Mar 29, 2013
@guyzmo guyzmo added es3 config option and updated tests to match es3 ;
made es5 the default and updated tests to remove es5 ;
added info message to tell about es5 being default ;
added functions to encapsulate management of current version state

Signed-off-by: Bernard `Guyzmo` Pratz <guyzmo+github@m0g.net>
c001e7c
@guyzmo guyzmo added support for asynchronous triggers defined in the lexer, but lau…
…nched in the parser for correct state context handling.

removed jsonMode/jsonWarnings hacks for JSON parsing

Signed-off-by: Bernard `Guyzmo` Pratz <guyzmo+github@m0g.net>
86e32f1
@guyzmo guyzmo added support for fat arrows ;
added application() function that handles parsing of arrow functions ;
updated functionparams/doFunction to support arrow functions ;
added tests ;

Signed-off-by: Bernard `Guyzmo` Pratz <guyzmo+github@m0g.net>
33db139
Commits on Apr 09, 2013
@valueof valueof Merge branch '952' of git://github.com/guyzmo/jshint into guyzmo-952
Conflicts:
	tests/stable/unit/parser.js
650fb72
@valueof valueof Merge branch 'master' into guyzmo-952 e32ae7e
View
3  src/shared/messages.js
@@ -194,7 +194,8 @@ var warnings = {
var info = {
I001: "Comma warnings can be turned off with 'laxcomma'.",
- I002: "Reserved words as properties can be used under the 'es5' option."
+ I002: "Reserved words as properties can be used under the 'es5' option.",
+ I003: "ES5 option is now set per default"
};
exports.errors = {};
View
212 src/stable/jshint.js
@@ -87,7 +87,8 @@ var JSHINT = (function () {
dojo : true, // if Dojo Toolkit globals should be predefined
eqeqeq : true, // if === should be required
eqnull : true, // if == null comparisons should be tolerated
- es5 : true, // if ES5 syntax should be allowed
+ es3 : true, // if ES3 syntax should be allowed
+ es5 : true, // if ES5 syntax should be allowed (is now set per default)
esnext : true, // if es.next specific syntax should be allowed
moz : true, // if mozilla specific syntax should be allowed
evil : true, // if eval should be allowed
@@ -273,7 +274,7 @@ var JSHINT = (function () {
if (token.meta && token.meta.isFutureReservedWord) {
// ES3 FutureReservedWord in an ES5 environment.
- if (state.option.es5 && !token.meta.es5) {
+ if (state.option.inES5(true) && !token.meta.es5) {
return false;
}
@@ -316,6 +317,9 @@ var JSHINT = (function () {
}
function assume() {
+ if (state.option.es5) {
+ warning("I003");
+ }
if (state.option.couch) {
combine(predefined, vars.couch);
}
@@ -375,14 +379,32 @@ var JSHINT = (function () {
if (state.option.yui) {
combine(predefined, vars.yui);
}
- }
- // let's assume that chronologically ES5 < ES6/ESNext < Moz
- function isAfterESNext() {
- return state.option.moz || state.option.esnext;
- }
- function isAfterES5() {
- return state.option.moz || state.option.esnext || state.option.es5;
+ // let's assume that chronologically ES3 < ES5 < ES6/ESNext < Moz
+ state.option.inMoz = function (strict) {
+ if (strict) {
+ return state.option.moz && !state.option.esnext;
+ }
+ return state.option.moz;
+ };
+ state.option.inESNext = function (strict) {
+ if (strict) {
+ return !state.option.moz && state.option.esnext;
+ }
+ return state.option.moz || state.option.esnext;
+ };
+ state.option.inES5 = function (strict) {
+ if (strict) {
+ return !state.option.moz && !state.option.esnext && !state.option.es3;
+ }
+ return !state.option.es3;
+ };
+ state.option.inES3 = function (strict) {
+ if (strict) {
+ return !state.option.moz && !state.option.esnext && state.option.es3;
+ }
+ return state.option.es3;
+ };
}
// Produce an error warning.
@@ -807,6 +829,10 @@ var JSHINT = (function () {
return;
}
+ if (state.tokens.next.check) {
+ state.tokens.next.check();
+ }
+
if (state.tokens.next.isSpecial) {
doOption();
} else {
@@ -836,7 +862,7 @@ var JSHINT = (function () {
// if current expression is a let expression
if (!initial && state.tokens.next.value === "let" && peek(0).value === "(") {
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.next, "let expressions");
}
isLetExpr = true;
@@ -1028,7 +1054,7 @@ var JSHINT = (function () {
nonadjacent(state.tokens.curr, state.tokens.next);
}
- if (state.tokens.next.identifier && !state.option.es5) {
+ if (state.tokens.next.identifier && !state.option.inES5()) {
// Keywords that cannot follow a comma operator.
switch (state.tokens.next.value) {
case "break":
@@ -1193,6 +1219,25 @@ var JSHINT = (function () {
return x;
}
+
+ function application(s) {
+ var x = symbol(s, 42);
+
+ x.led = function (left) {
+ if (!state.option.inESNext()) {
+ warning("W104", state.tokens.curr, "arrow function syntax (=>)");
+ }
+
+ nobreaknonadjacent(state.tokens.prev, state.tokens.curr);
+ nonadjacent(state.tokens.curr, state.tokens.next);
+
+ this.left = left;
+ this.right = doFunction(undefined, undefined, false, left);
+ return this;
+ };
+ return x;
+ }
+
function relation(s, f) {
var x = symbol(s, 100);
@@ -1365,7 +1410,7 @@ var JSHINT = (function () {
}
if (prop) {
- if (state.option.es5 || meta.isFutureReservedWord) {
+ if (state.option.inES5() || meta.isFutureReservedWord) {
return val;
}
}
@@ -1453,7 +1498,7 @@ var JSHINT = (function () {
// detect a destructuring assignment
if (_.has(["[", "{"], t.value)) {
if (lookupBlockType().isDestAssign) {
- if (!isAfterESNext()) {
+ if (!state.option.inESNext()) {
warning("W104", state.tokens.curr, "destructuring expression");
}
values = destructuringExpression();
@@ -1624,7 +1669,7 @@ var JSHINT = (function () {
* stmt - true if block can be a single statement (e.g. in if/for/while).
* isfunc - true if block is a function body
*/
- function block(ordinary, stmt, isfunc) {
+ function block(ordinary, stmt, isfunc, isfatarrow) {
var a,
b = inblock,
old_indent = indent,
@@ -1697,14 +1742,16 @@ var JSHINT = (function () {
indent = old_indent;
} else if (!ordinary) {
if (isfunc) {
- if (stmt && !state.option.moz) {
+ if (stmt && !isfatarrow && !state.option.inMoz(true)) {
error("W118", state.tokens.curr, "function closure expressions");
}
- m = {};
- for (d in state.directive) {
- if (_.has(state.directive, d)) {
- m[d] = state.directive[d];
+ if (!stmt) {
+ m = {};
+ for (d in state.directive) {
+ if (_.has(state.directive, d)) {
+ m[d] = state.directive[d];
+ }
}
}
expression(0);
@@ -2278,7 +2325,17 @@ var JSHINT = (function () {
}, 155, true).exps = true;
prefix("(", function () {
+
nospace();
+ var bracket, brackets = [];
+ var pn, pn1, i = 0;
+
+ do {
+ pn = peek(i);
+ i += 1;
+ pn1 = peek(i);
+ i += 1;
+ } while (pn.value !== ")" && pn1.value !== "=>" && pn1.value !== ";" && pn1.type !== "(end)");
if (state.tokens.next.id === "function") {
state.tokens.next.immed = true;
@@ -2288,7 +2345,16 @@ var JSHINT = (function () {
if (state.tokens.next.id !== ")") {
for (;;) {
- exprs.push(expression(0));
+ if (pn1.value === "=>" && state.tokens.next.value === "{") {
+ bracket = state.tokens.next;
+ bracket.left = destructuringExpression();
+ brackets.push(bracket);
+ for (var t in bracket.left) {
+ exprs.push(bracket.left[t].token);
+ }
+ } else {
+ exprs.push(expression(0));
+ }
if (state.tokens.next.id !== ",") {
break;
}
@@ -2305,9 +2371,14 @@ var JSHINT = (function () {
}
}
+ if (state.tokens.next.value === "=>") {
+ return exprs;
+ }
return exprs[0];
});
+ application("=>");
+
infix("[", function (left, that) {
nobreak(state.tokens.prev, state.tokens.curr);
nospace();
@@ -2346,7 +2417,7 @@ var JSHINT = (function () {
advance("for");
if (state.tokens.next.value === "each") {
advance("each");
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.curr, "for each");
}
}
@@ -2369,11 +2440,11 @@ var JSHINT = (function () {
prefix("[", function () {
var blocktype = lookupBlockType(true);
if (blocktype.isCompArray) {
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.curr, "array comprehension");
}
return comprehensiveArrayExpression();
- } else if (blocktype.isDestAssign && !isAfterESNext()) {
+ } else if (blocktype.isDestAssign && !state.option.inESNext()) {
warning("W104", state.tokens.curr, "destructuring assignment");
}
var b = state.tokens.curr.line !== state.tokens.next.line;
@@ -2386,7 +2457,7 @@ var JSHINT = (function () {
}
while (state.tokens.next.id !== "(end)") {
while (state.tokens.next.id === ",") {
- if (!isAfterES5())
+ if (!state.option.inES5())
warning("W070");
advance(",");
}
@@ -2399,7 +2470,7 @@ var JSHINT = (function () {
this.first.push(expression(10));
if (state.tokens.next.id === ",") {
comma({ allowTrailing: true });
- if (state.tokens.next.id === "]" && !state.option.es5) {
+ if (state.tokens.next.id === "]" && !state.option.inES5(true)) {
warning("W070", state.tokens.curr);
break;
}
@@ -2437,11 +2508,39 @@ var JSHINT = (function () {
}
- function functionparams() {
- var next = state.tokens.next;
+ function functionparams(parsed) {
+ var curr, next;
var params = [];
var ident;
var tokens = [];
+ var t;
+
+ if (parsed) {
+ if (parsed instanceof Array) {
+ for (var i in parsed) {
+ curr = parsed[i];
+ if (_.contains(["{", "["], curr.id)) {
+ for (t in curr.left) {
+ t = tokens[t];
+ if (t.id) {
+ params.push(t.id);
+ addlabel(t.id, "unused", t.token);
+ }
+ }
+ } else {
+ addlabel(curr.value, "unused", curr);
+ }
+ }
+ return params;
+ } else {
+ if (parsed.identifier === true) {
+ addlabel(parsed.value, "unused", parsed);
+ return [parsed];
+ }
+ }
+ }
+
+ next = state.tokens.next;
advance("(");
nospace();
@@ -2454,7 +2553,7 @@ var JSHINT = (function () {
for (;;) {
if (_.contains(["{", "["], state.tokens.next.id)) {
tokens = destructuringExpression();
- for (var t in tokens) {
+ for (t in tokens) {
t = tokens[t];
if (t.id) {
params.push(t.id);
@@ -2477,7 +2576,7 @@ var JSHINT = (function () {
}
- function doFunction(name, statement, generator) {
+ function doFunction(name, statement, generator, fatarrowparams) {
var f;
var oldOption = state.option;
var oldScope = scope;
@@ -2513,10 +2612,11 @@ var JSHINT = (function () {
addlabel(name, "function");
}
- funct["(params)"] = functionparams();
+ funct["(params)"] = functionparams(fatarrowparams);
+
funct["(metrics)"].verifyMaxParametersPerFunction(funct["(params)"]);
- block(false, true, true);
+ block(false, true, true, fatarrowparams ? true:false);
if (generator && funct["(generator)"] !== "yielded") {
error("E047", state.tokens.curr);
@@ -2660,7 +2760,7 @@ var JSHINT = (function () {
if (state.tokens.next.value === "get" && peek().id !== ":") {
advance("get");
- if (!state.option.es5) {
+ if (!state.option.inES5(true)) {
error("E034");
}
@@ -2683,7 +2783,7 @@ var JSHINT = (function () {
} else if (state.tokens.next.value === "set" && peek().id !== ":") {
advance("set");
- if (!state.option.es5) {
+ if (!state.option.inES5(true)) {
error("E034");
}
@@ -2719,7 +2819,7 @@ var JSHINT = (function () {
comma({ allowTrailing: true });
if (state.tokens.next.id === ",") {
warning("W070", state.tokens.curr);
- } else if (state.tokens.next.id === "}" && !state.option.es5) {
+ } else if (state.tokens.next.id === "}" && !state.option.inES5(true)) {
warning("W070", state.tokens.curr);
}
} else {
@@ -2733,7 +2833,7 @@ var JSHINT = (function () {
advance("}", this);
// Check for lonely setters if in the ES5 mode.
- if (state.option.es5) {
+ if (state.option.inES5()) {
for (var name in props) {
if (_.has(props, name) && props[name].setter && !props[name].getter) {
warning("W078", props[name].setterToken);
@@ -2750,7 +2850,7 @@ var JSHINT = (function () {
function destructuringExpression() {
var id, ids;
var identifiers = [];
- if (!isAfterESNext()) {
+ if (!state.option.inESNext()) {
warning("W104", state.tokens.curr, "destructuring expression");
}
var nextInnerDE = function () {
@@ -2821,7 +2921,7 @@ var JSHINT = (function () {
// state variable to know if it is a lone identifier, or a destructuring statement.
var lone;
- if (!isAfterESNext()) {
+ if (!state.option.inESNext()) {
warning("W104", state.tokens.curr, "const");
}
@@ -2909,7 +3009,7 @@ var JSHINT = (function () {
}
for (var t in tokens) {
t = tokens[t];
- if (isAfterESNext() && funct[t.id] === "const") {
+ if (state.option.inESNext() && funct[t.id] === "const") {
warning("E011", null, t.id);
}
if (funct["(global)"] && predefined[t.id] === false) {
@@ -2955,12 +3055,12 @@ var JSHINT = (function () {
var letstatement = stmt("let", function (prefix) {
var tokens, lone, value, letblock;
- if (!isAfterESNext()) {
+ if (!state.option.inESNext()) {
warning("W104", state.tokens.curr, "let");
}
if (state.tokens.next.value === "(") {
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.next, "let block");
}
advance("(");
@@ -2989,7 +3089,7 @@ var JSHINT = (function () {
}
for (var t in tokens) {
t = tokens[t];
- if (isAfterESNext() && funct[t.id] === "const") {
+ if (state.option.inESNext() && funct[t.id] === "const") {
warning("E011", null, t.id);
}
if (funct["(global)"] && predefined[t.id] === false) {
@@ -3044,7 +3144,7 @@ var JSHINT = (function () {
var generator = false;
if (state.tokens.next.value === "*") {
advance("*");
- if (state.option.esnext && !state.option.moz) {
+ if (state.option.inESNext(true)) {
generator = true;
} else {
warning("W119", state.tokens.curr, "function*");
@@ -3071,7 +3171,7 @@ var JSHINT = (function () {
prefix("function", function () {
var generator = false;
if (state.tokens.next.value === "*") {
- if (!state.option.esnext) {
+ if (!state.option.inESNext()) {
warning("W119", state.tokens.curr, "function*");
}
advance("*");
@@ -3155,7 +3255,7 @@ var JSHINT = (function () {
}
if (state.tokens.next.value === "if") {
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.curr, "catch filter");
}
advance("if");
@@ -3180,7 +3280,7 @@ var JSHINT = (function () {
while (state.tokens.next.id === "catch") {
increaseComplexityCount();
- if (b && (!state.option.moz)) {
+ if (b && (!state.option.inMoz(true))) {
warning("W118", state.tokens.next, "multiple catch blocks");
}
doCatch();
@@ -3381,7 +3481,7 @@ var JSHINT = (function () {
if (t.value === "each") {
foreachtok = t;
advance("each");
- if (!state.option.moz) {
+ if (!state.option.inMoz(true)) {
warning("W118", state.tokens.curr, "for each");
}
}
@@ -3405,7 +3505,7 @@ var JSHINT = (function () {
// if we're in a for (… in|of …) statement
if (_.contains(inof, nextop.value)) {
- if (!isAfterESNext() && nextop.value === "of") {
+ if (!state.option.inESNext() && nextop.value === "of") {
error("W104", nextop, "for of");
}
if (state.tokens.next.id === "var") {
@@ -3573,9 +3673,9 @@ var JSHINT = (function () {
}).exps = true;
stmt("yield", function () {
- if (state.option.esnext && funct["(generator)"] !== true) {
+ if (state.option.inESNext(true) && funct["(generator)"] !== true) {
error("E046", state.tokens.curr, "yield");
- } else if (!isAfterESNext()) {
+ } else if (!state.option.inESNext()) {
warning("W104", state.tokens.curr, "yield");
}
funct["(generator)"] = "yielded";
@@ -3641,13 +3741,11 @@ var JSHINT = (function () {
// this function is used to determine wether a squarebracket or a curlybracket
// expression is a comprehension array, destructuring assignment or a json value.
- var lookupBlockType = function (notjson) {
+ var lookupBlockType = function () {
var pn, pn1;
var i = 0;
var bracketStack = 0;
var ret = {};
- state.jsonMode = "probing";
- state.jsonWarnings = [];
if (_.contains(["[", "{"], state.tokens.curr.value))
bracketStack += 1;
if (_.contains(["[", "{"], state.tokens.next.value))
@@ -3678,14 +3776,6 @@ var JSHINT = (function () {
ret.notJson = true;
}
} while (bracketStack > 0 && pn.id !== "(end)" && i < 15);
- if (!ret.notJson && !notjson) {
- for (var w in state.jsonWarnings) {
- w = state.jsonWarnings[w];
- warningAt(w.code, w.line, w.character, w.data && w.data[0]);
- }
- }
- state.jsonMode = false;
- delete state.jsonWarnings;
return ret;
};
@@ -3697,7 +3787,7 @@ var JSHINT = (function () {
var block = lookupBlockType();
if (block.notJson) {
- if (!isAfterESNext() && block.isDestAssign) {
+ if (!state.option.inESNext() && block.isDestAssign) {
warning("W104", state.tokens.curr, "destructuring assignment");
}
statements();
View
227 src/stable/lex.js
@@ -153,6 +153,27 @@ for (var i = 0; i < 128; i++) {
i >= 48 && i <= 57; // 0-9
}
+// Object that handles postponed lexing verifications that checks the parsed
+// environment state.
+
+function asyncTrigger() {
+ var _checks = [];
+
+ return {
+ push: function (fn) {
+ _checks.push(fn);
+ },
+
+ check: function () {
+ for (var check in _checks) {
+ _checks[check]();
+ }
+
+ _checks.splice(0, _checks.length);
+ }
+ };
+}
+
/*
* Lexer for JSHint.
*
@@ -265,6 +286,21 @@ Lexer.prototype = {
},
/*
+ * Postpone a token event. the checking condition is set as
+ * last parameter, and the trigger function is called in a
+ * stored callback. To be later called using the check() function
+ * by the parser. This avoids parser's peek() to give the lexer
+ * a false context.
+ */
+ triggerAsync: function (type, args, checks, fn) {
+ checks.push(function () {
+ if (fn()) {
+ this.trigger(type, args);
+ }
+ }.bind(this));
+ },
+
+ /*
* Extract a punctuator out of the next sequence of characters
* or return 'null' if its not possible.
*
@@ -363,6 +399,14 @@ Lexer.prototype = {
};
}
+ // Fat arrow punctuator
+ if (ch1 === "=" && ch2 === ">") {
+ return {
+ type: Token.Punctuator,
+ value: ch1 + ch2
+ };
+ }
+
// 2-character punctuators: <= >= == != ++ -- << >> && ||
// += -= *= %= &= |= ^= (but not /=, see below)
if (ch1 === ch2 && ("+-<>&|".indexOf(ch1) >= 0)) {
@@ -935,7 +979,8 @@ Lexer.prototype = {
* var str = "hello\
* world";
*/
- scanStringLiteral: function () {
+ scanStringLiteral: function (checks) {
+ /*jshint loopfunc:true */
var quote = this.peek();
// String must start with a quote.
@@ -944,21 +989,11 @@ Lexer.prototype = {
}
// In JSON strings must always use double quotes.
- if (quote !== "\"") {
- if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W108",
- line: this.line,
- character: this.char // +1?
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W108",
- line: this.line,
- character: this.char // +1?
- });
- }
- }
+ this.triggerAsync("warning", {
+ code: "W108",
+ line: this.line,
+ character: this.char // +1?
+ }, checks, function () { return state.jsonMode && quote !== "\""; });
var value = "";
var startLine = this.line;
@@ -989,25 +1024,17 @@ Lexer.prototype = {
// Otherwise show a warning if multistr option was not set.
// For JSON, show warning no matter what.
- if (!state.option.multistr) {
- this.trigger("warning", {
- code: "W043",
- line: this.line,
- character: this.char
- });
- } else if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W042",
- line: this.line,
- character: this.char
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W042",
- line: this.line,
- character: this.char
- });
- }
+ this.triggerAsync("warning", {
+ code: "W043",
+ line: this.line,
+ character: this.char
+ }, checks, function () { return !state.option.multistr; });
+
+ this.triggerAsync("warning", {
+ code: "W042",
+ line: this.line,
+ character: this.char
+ }, checks, function () { return state.jsonMode && state.option.multistr; });
}
// If we get an EOF inside of an unclosed string, show an
@@ -1052,21 +1079,12 @@ Lexer.prototype = {
switch (char) {
case "'":
- if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\'" ]
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\'" ]
- });
- }
+ this.triggerAsync("warning", {
+ code: "W114",
+ line: this.line,
+ character: this.char,
+ data: [ "\\'" ]
+ }, checks, function () {return state.jsonMode; });
break;
case "b":
char = "\b";
@@ -1089,55 +1107,36 @@ Lexer.prototype = {
// Octal literals fail in strict mode.
// Check if the number is between 00 and 07.
var n = parseInt(this.peek(1), 10);
- if (n >= 0 && n <= 7 && state.directive["use strict"]) {
- this.trigger("warning", {
- code: "W115",
- line: this.line,
- character: this.char
- });
- }
+ this.triggerAsync("warning", {
+ code: "W115",
+ line: this.line,
+ character: this.char
+ }, checks,
+ function () { return n >= 0 && n <= 7 && state.directive["use strict"]; });
break;
case "u":
char = String.fromCharCode(parseInt(this.input.substr(1, 4), 16));
jump = 5;
break;
case "v":
- if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\v" ]
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\v" ]
- });
- }
+ this.triggerAsync("warning", {
+ code: "W114",
+ line: this.line,
+ character: this.char,
+ data: [ "\\v" ]
+ }, checks, function () { return state.jsonMode; });
char = "\v";
break;
case "x":
var x = parseInt(this.input.substr(1, 2), 16);
- if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\x-" ]
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "\\x-" ]
- });
- }
+ this.triggerAsync("warning", {
+ code: "W114",
+ line: this.line,
+ character: this.char,
+ data: [ "\\x-" ]
+ }, checks, function () { return state.jsonMode; });
char = String.fromCharCode(x);
jump = 3;
@@ -1377,7 +1376,7 @@ Lexer.prototype = {
* Produce the next raw token or return 'null' if no tokens can be matched.
* This method skips over all space characters.
*/
- next: function () {
+ next: function (checks) {
this.from = this.char;
// Move to the next non-space character.
@@ -1401,7 +1400,7 @@ Lexer.prototype = {
// character pointer.
var match = this.scanComments() ||
- this.scanStringLiteral();
+ this.scanStringLiteral(checks);
if (match) {
return match;
@@ -1478,6 +1477,8 @@ Lexer.prototype = {
* the next token. It retuns a token in a JSLint-compatible format.
*/
token: function () {
+ /*jshint loopfunc:true */
+ var checks = asyncTrigger();
var token;
function isReserved(token, isProperty) {
@@ -1487,7 +1488,7 @@ Lexer.prototype = {
if (token.meta && token.meta.isFutureReservedWord) {
// ES3 FutureReservedWord in an ES5 environment.
- if (state.option.es5 && !token.meta.es5) {
+ if (state.option.inES5(true) && !token.meta.es5) {
return false;
}
@@ -1562,6 +1563,8 @@ Lexer.prototype = {
obj.isProperty = isProperty;
}
+ obj.check = checks.check;
+
return obj;
}.bind(this);
@@ -1570,7 +1573,7 @@ Lexer.prototype = {
return create(this.nextLine() ? "(endline)" : "(end)", "");
}
- token = this.next();
+ token = this.next(checks);
if (!token) {
if (this.input.length) {
@@ -1590,13 +1593,13 @@ Lexer.prototype = {
switch (token.type) {
case Token.StringLiteral:
- this.trigger("String", {
+ this.triggerAsync("String", {
line: this.line,
char: this.char,
from: this.from,
value: token.value,
quote: token.quote
- });
+ }, checks, function () { return true; });
return create("(string)", token.value);
case Token.Identifier:
@@ -1624,31 +1627,21 @@ Lexer.prototype = {
});
}
- if (token.base === 16) {
- if (state.jsonMode === "probing") {
- state.jsonWarnings.push({
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "0x-" ]
- });
- } else if (state.jsonMode) {
- this.trigger("warning", {
- code: "W114",
- line: this.line,
- character: this.char,
- data: [ "0x-" ]
- });
- }
- }
+ this.triggerAsync("warning", {
+ code: "W114",
+ line: this.line,
+ character: this.char,
+ data: [ "0x-" ]
+ }, checks, function () { return token.base === 16 && state.jsonMode; });
- if (state.directive["use strict"] && token.base === 8) {
- this.trigger("warning", {
- code: "W115",
- line: this.line,
- character: this.char
- });
- }
+ this.triggerAsync("warning", {
+ code: "W115",
+ line: this.line,
+ character: this.char
+ }, checks, function () {
+ // console.log("W115", state.directive["use strict"], token.base === 8);
+ return state.directive["use strict"] && token.base === 8;
+ });
this.trigger("Number", {
line: this.line,
View
68 tests/stable/unit/core.js
@@ -35,7 +35,7 @@ exports.testCustomGlobals = function (test) {
TestRun(test)
.addError(2, "Read only.")
.addError(3, "Read only.")
- .test(code, { unused: true, predef: { foo: false }});
+ .test(code, { es3: true, unused: true, predef: { foo: false }});
test.done();
};
@@ -45,7 +45,7 @@ exports.testUnusedDefinedGlobals = function (test) {
TestRun(test)
.addError(2, "'bar' is defined but never used.")
- .test(src, { unused: true });
+ .test(src, { es3: true, unused: true });
test.done();
};
@@ -225,7 +225,7 @@ exports.testMissingSpaces = function (test) {
.addError(8, "Missing space after '+'.", { character: 21 })
.addError(8, "Missing space after '/likes?access_token='.", { character: 43 })
.addError(8, "Missing space after '+'.", { character: 44 })
- .test(src, { white: true });
+ .test(src, { es3: true, white: true });
test.done();
};
@@ -235,10 +235,10 @@ exports.testGoogleClosureLinterCompatibility = function (test) {
TestRun(test)
.addError(1, "Missing space after 'function'.")
- .test(code, { white: true });
+ .test(code, { es3: true, white: true });
TestRun(test)
- .test(code, { white: true, gcl: true });
+ .test(code, { es3: true, white: true, gcl: true });
test.done();
};
@@ -300,7 +300,7 @@ exports.returnStatement = function (test) {
TestRun(test)
.addError(3, "Did you mean to return a conditional instead of an assignment?")
.addError(38, "Line breaking error 'return'.")
- .test(src, { maxerr: 2 });
+ .test(src, { es3: true, maxerr: 2 });
test.done();
};
@@ -309,7 +309,7 @@ exports.globalDeclarations = function (test) {
var src = 'exports = module.exports = function (test) {};';
// Test should pass
- TestRun(test).test(src, { node: true }, { exports: true });
+ TestRun(test).test(src, { es3: true, node: true }, { exports: true });
// Test should pass as well
src = [
@@ -329,7 +329,7 @@ exports.argsInCatchReused = function (test) {
.addError(6, "'e' is already defined.")
.addError(12, "Do not assign to the exception parameter.")
.addError(23, "'e' is not defined.")
- .test(src, { undef: true });
+ .test(src, { es3: true, undef: true });
test.done();
};
@@ -351,13 +351,13 @@ exports.yesEmptyStmt = function (test) {
.addError(6, "Expected an assignment or function call and instead saw an expression.")
.addError(10, "Unnecessary semicolon.")
.addError(17, "Unnecessary semicolon.")
- .test(src, { curly: false });
+ .test(src, { es3: true, curly: false });
TestRun(test)
.addError(1, "Expected an identifier and instead saw ';'.")
.addError(10, "Unnecessary semicolon.")
.addError(17, "Unnecessary semicolon.")
- .test(src, { curly: false, expr: true });
+ .test(src, { es3: true, curly: false, expr: true });
test.done();
};
@@ -383,7 +383,7 @@ exports.insideEval = function (test) {
.addError(1, "Expected ')' and instead saw ''.")
.addError(1, "Missing semicolon.")
- .test(src, { evil: false });
+ .test(src, { es3: true, evil: false });
// Regression test for bug GH-714.
JSHINT(src, { evil: false, maxerr: 1 });
@@ -406,7 +406,7 @@ exports.noExcOnTooManyUndefined = function (test) {
TestRun(test)
.addError(1, "'a' is not defined.")
- .test(code, { undef: true, maxerr: 1 });
+ .test(code, { es3: true, undef: true, maxerr: 1 });
test.done();
};
@@ -417,7 +417,7 @@ exports.defensiveSemicolon = function (test) {
TestRun(test)
.addError(16, "Unnecessary semicolon.")
.addError(17, "Unnecessary semicolon.")
- .test(src, { expr: true, laxbreak: true });
+ .test(src, { es3: true, expr: true, laxbreak: true });
test.done();
};
@@ -439,7 +439,7 @@ exports.iife = function (test) {
exports.invalidOptions = function (test) {
TestRun(test)
.addError(0, "Bad option: 'invalid'.")
- .test("function test() {}", { devel: true, invalid: true });
+ .test("function test() {}", { es3: true, devel: true, invalid: true });
test.done();
};
@@ -463,13 +463,13 @@ exports.testInvalidSource = function (test) {
TestRun(test)
.addError(0, "Input is neither a string nor an array of strings.")
- .test({});
+ .test({}, {es3: true});
TestRun(test)
- .test("");
+ .test("", {es3: true});
TestRun(test)
- .test([]);
+ .test([], {es3: true});
test.done();
};
@@ -481,7 +481,7 @@ exports.testConstructor = function (test) {
.addError(1, "Do not use Number as a constructor.", {
character: 1
})
- .test(code);
+ .test(code, {es3: true});
test.done();
};
@@ -493,23 +493,23 @@ exports.missingRadix = function (test) {
.addError(1, "Missing radix parameter.", {
character: 12
})
- .test(code);
+ .test(code, {es3: true});
test.done();
};
exports.NumberNaN = function (test) {
var code = "(function (test) { return Number.NaN; })();";
- TestRun(test).test(code);
+ TestRun(test).test(code, {es3: true});
test.done();
};
exports.htmlEscapement = function (test) {
- TestRun(test).test("var a = '<\\!--';");
+ TestRun(test).test("var a = '<\\!--';", {es3: true});
TestRun(test)
.addError(1, "Bad or unnecessary escaping.")
- .test("var a = '\\!';");
+ .test("var a = '\\!';", {es3: true});
test.done();
};
@@ -523,10 +523,10 @@ exports.testSparseArrays = function (test) {
.addError(1, "Extra comma. (it breaks older versions of IE)")
.addError(1, "Extra comma. (it breaks older versions of IE)")
.addError(1, "Extra comma. (it breaks older versions of IE)")
- .test(src);
+ .test(src, {es3: true});
TestRun(test)
- .test(src, { es5: true });
+ .test(src, {}); // es5
test.done();
};
@@ -540,12 +540,12 @@ exports.testReserved = function (test) {
.addError(10, "Expected an identifier and instead saw 'let' (a reserved word).")
.addError(14, "Expected an identifier and instead saw 'else' (a reserved word).")
.addError(14, "Reserved words as properties can be used under the 'es5' option.")
- .test(src);
+ .test(src, {es3: true});
TestRun(test)
.addError(5, "Expected an identifier and instead saw 'let' (a reserved word).")
.addError(10, "Expected an identifier and instead saw 'let' (a reserved word).")
- .test(src, { es5: true });
+ .test(src, {}); // es5
test.done();
};
@@ -566,14 +566,14 @@ exports.testES5Reserved = function (test) {
.addError(9, "Expected an identifier and instead saw 'default' (a reserved word).")
.addError(10, "Expected an identifier and instead saw 'in' (a reserved word).")
.addError(11, "Expected an identifier and instead saw 'in' (a reserved word).")
- .test(src);
+ .test(src, {es3: true});
TestRun(test)
.addError(6, "Expected an identifier and instead saw 'default' (a reserved word).")
.addError(7, "Expected an identifier and instead saw 'new' (a reserved word).")
.addError(8, "Expected an identifier and instead saw 'class' (a reserved word).")
.addError(11, "Expected an identifier and instead saw 'in' (a reserved word).")
- .test(src, { es5: true });
+ .test(src, {}); // es5
test.done();
};
@@ -583,16 +583,16 @@ exports.testCatchBlocks = function (test) {
TestRun(test)
.addError(11, "'w' is not defined.")
- .test(src, { undef: true, devel: true });
+ .test(src, { es3: true, undef: true, devel: true });
src = fs.readFileSync(__dirname + '/fixtures/gh618.js', 'utf8');
TestRun(test)
.addError(5, "Value of 'x' may be overwritten in IE.")
- .test(src, { undef: true, devel: true });
+ .test(src, { es3: true, undef: true, devel: true });
TestRun(test)
- .test(src, { undef: true, devel: true, node: true });
+ .test(src, { es3: true, undef: true, devel: true, node: true });
test.done();
};
@@ -616,7 +616,7 @@ exports.testForIn = function (test) {
];
TestRun(test)
- .test(src);
+ .test(src, {es3: true});
src = [
"(function (o) {",
@@ -626,7 +626,7 @@ exports.testForIn = function (test) {
TestRun(test)
.addError(2, "Creating global 'for' variable. Should be 'for (var i ...'.")
- .test(src);
+ .test(src, {es3: true});
test.done();
};
@@ -635,7 +635,7 @@ exports.testRegexArray = function (test) {
var src = fs.readFileSync(__dirname + "/fixtures/regex_array.js", "utf8");
TestRun(test)
- .test(src);
+ .test(src, {es3: true});
test.done();
};
View
20 tests/stable/unit/envs.js
@@ -80,12 +80,12 @@ exports.node = function (test) {
"console.log(__hello);",
];
- TestRun(test).test(asGlobals, { node: true, nomen: true });
+ TestRun(test).test(asGlobals, { es3: true, node: true, nomen: true });
TestRun(test)
.addError(1, "Unexpected dangling '_' in '__dirname'.")
.addError(2, "Unexpected dangling '_' in '__filename'.")
.addError(3, "Unexpected dangling '_' in '__hello'.")
- .test(asProps, { node: true, nomen: true });
+ .test(asProps, { es3: true, node: true, nomen: true });
// Node environment assumes `globalstrict`
var globalStrict = [
@@ -95,14 +95,14 @@ exports.node = function (test) {
TestRun(test)
.addError(1, 'Use the function form of "use strict".')
- .test(globalStrict, { strict: true });
+ .test(globalStrict, { es3: true, strict: true });
TestRun(test)
- .test(globalStrict, { node: true, strict: true });
+ .test(globalStrict, { es3: true, node: true, strict: true });
// Don't assume strict:true for Node environments. See bug GH-721.
TestRun(test)
- .test("function test() { return; }", { node: true });
+ .test("function test() { return; }", { es3: true, node: true });
// Make sure that we can do fancy Node export
@@ -113,7 +113,7 @@ exports.node = function (test) {
TestRun(test)
.addError(1, "Read only.")
- .test(overwrites, { node: true });
+ .test(overwrites, { es3: true, node: true });
test.done();
};
@@ -123,7 +123,7 @@ exports.jquery = function (test) {
var globals = ['jQuery', "$"];
globalsImplied(test, globals);
- globalsKnown(test, globals, { jquery: true });
+ globalsKnown(test, globals, { es3: true, jquery: true });
test.done();
};
@@ -464,7 +464,7 @@ exports.es5 = function (test) {
.addError(69, "Missing property name.")
.addError(75, "get/set are ES5 features.")
.addError(76, "get/set are ES5 features.")
- .test(src);
+ .test(src, { es3: true });
TestRun(test)
.addError(36, "Setter is defined without getter.")
@@ -477,12 +477,12 @@ exports.es5 = function (test) {
.addError(64, "Expected a single parameter in set z function.")
.addError(68, "Missing property name.")
.addError(69, "Missing property name.")
- .test(src, { es5: true });
+ .test(src, { }); // es5
// Make sure that JSHint parses getters/setters as function expressions
// (https://github.com/jshint/jshint/issues/96)
src = fs.readFileSync(__dirname + "/fixtures/es5.funcexpr.js", "utf8");
- TestRun(test).test(src, { es5: true });
+ TestRun(test).test(src, { }); // es5
test.done();
};
View
4 tests/stable/unit/fixtures/unused.js
@@ -18,9 +18,9 @@ function foo(err, cb) {
}
function bar(g, h) {
- //jshint unused:false, es5:true
+ //jshint unused:false, es3:false
var i = 1;
var char;
char = 1;
return h;
-}
+}
View
338 tests/stable/unit/options.js
@@ -28,11 +28,11 @@ exports.shadow = function (test) {
TestRun(test)
.addError(5, "'a' is already defined.")
.addError(10, "'foo' is already defined.")
- .test(src);
+ .test(src, {es3: true});
// Allow variable shadowing when shadow is true
TestRun(test)
- .test(src, { shadow: true });
+ .test(src, { es3: true, shadow: true });
test.done();
};
@@ -55,32 +55,32 @@ exports.latedef = function (test) {
// By default, tolerate the use of variable before its definition
TestRun(test)
- .test(src);
+ .test(src, {es3: true});
// However, JSHint must complain if variable is actually missing
TestRun(test)
.addError(1, "'fn' is not defined.")
- .test('fn();', { undef: true });
+ .test('fn();', { es3: true, undef: true });
// And it also must complain about the redefinition (see option `shadow`)
TestRun(test)
.addError(5, "'a' is already defined.")
.addError(10, "'foo' is already defined.")
- .test(src1);
+ .test(src1, { es3: true });
- // When latedef is "nofunc", JSHint must not tolerate the use before definition
+ // When latedef is true, JSHint must not tolerate the use before definition
TestRun(test)
.addError(10, "'vr' was used before it was defined.")
.addError(18, "Inner functions should be listed at the top of the outer function.")
- .test(src, { latedef: "nofunc" });
+ .test(src, { es3: true, latedef: "nofunc" });
- // When latedef is true, JSHint must not tolerate the use before definition for functions
+ // When latedef_func is true, JSHint must not tolerate the use before definition for functions
TestRun(test)
.addError(2, "'fn' was used before it was defined.")
.addError(6, "'fn1' was used before it was defined.")
.addError(10, "'vr' was used before it was defined.")
.addError(18, "Inner functions should be listed at the top of the outer function.")
- .test(src, { latedef: true });
+ .test(src, { es3: true, latedef: true });
test.done();
};
@@ -93,11 +93,11 @@ exports['combination of latedef and undef'] = function (test) {
TestRun(test)
.addError(29, "'hello' is not defined.")
.addError(35, "'world' is not defined.")
- .test(src, { latedef: false, undef: true });
+ .test(src, { es3: true, latedef: false, undef: true });
// When we suppress `latedef` and `undef` then we get no warnings.
TestRun(test)
- .test(src, { latedef: false, undef: false });
+ .test(src, { es3: true, latedef: false, undef: false });
// If we warn on `latedef` but supress `undef` we only get the
// late definition warnings.
@@ -109,13 +109,13 @@ exports['combination of latedef and undef'] = function (test) {
.addError(34, "'fn' was used before it was defined.")
.addError(41, "'q' was used before it was defined.")
.addError(46, "'h' was used before it was defined.")
- .test(src, { latedef: true, undef: false });
+ .test(src, { es3: true, latedef: true, undef: false });
// But we get all the functions warning if we disable latedef func
TestRun(test)
.addError(41, "'q' was used before it was defined.")
.addError(46, "'h' was used before it was defined.")
- .test(src, { latedef: "nofunc", undef: false });
+ .test(src, { es3: true, latedef: "nofunc", undef: false });
// If we warn on both options we get all the warnings.
TestRun(test)
@@ -128,22 +128,22 @@ exports['combination of latedef and undef'] = function (test) {
.addError(35, "'world' is not defined.")
.addError(41, "'q' was used before it was defined.")
.addError(46, "'h' was used before it was defined.")
- .test(src, { latedef: true, undef: true });
+ .test(src, { es3: true, latedef: true, undef: true });
- // If we use latedef: "nofunc", we don't get the functions warning
+ // If we remove latedef_func, we don't get the functions warning
TestRun(test)
.addError(29, "'hello' is not defined.")
.addError(35, "'world' is not defined.")
.addError(41, "'q' was used before it was defined.")
.addError(46, "'h' was used before it was defined.")
- .test(src, { latedef: "nofunc", undef: true });
+ .test(src, { es3: true, latedef: "nofunc", undef: true });
test.done();
};
exports.undefwstrict = function (test) {
var src = fs.readFileSync(__dirname + '/fixtures/undefstrict.js', 'utf8');
- TestRun(test).test(src, { undef: false });
+ TestRun(test).test(src, { es3: true, undef: false });
test.done();
};
@@ -153,7 +153,7 @@ exports["implied and unused should respect hoisting"] = function (test) {
var src = fs.readFileSync(__dirname + '/fixtures/gh431.js', 'utf8');
TestRun(test)
.addError(14, "'fun4' is not defined.")
- .test(src, { undef: true });
+ .test(src, { undef: true }); // es5
JSHINT.flag = true;
JSHINT(src, { undef: true });
@@ -185,17 +185,17 @@ exports.testProtoAndIterator = function (test) {
.addError(27, "'__iterator__' is only available in JavaScript 1.7.")
.addError(33, "The '__proto__' property is deprecated.")
.addError(37, "The '__proto__' property is deprecated.")
- .test(source);
+ .test(source, {es3: true});
TestRun(test)
.addError(1, "The '__proto__' key may produce unexpected results.")
.addError(1, "The '__iterator__' key may produce unexpected results.")
- .test(json);
+ .test(json, {es3: true});
// Should not report any errors when proto and iterator
// options are on
- TestRun("source").test(source, { proto: true, iterator: true });
- TestRun("json").test(json, { proto: true, iterator: true });
+ TestRun("source").test(source, { es3: true, proto: true, iterator: true });
+ TestRun("json").test(json, { es3: true, proto: true, iterator: true });
test.done();
};
@@ -208,7 +208,7 @@ exports.testCamelcase = function (test) {
// By default, tolerate arbitrary identifiers
TestRun(test)
- .test(source);
+ .test(source, {es3: true});
// Require identifiers in camel case if camelcase is true
TestRun(test)
@@ -217,7 +217,7 @@ exports.testCamelcase = function (test) {
.addError(6, "Identifier 'test_me' is not in camel case.")
.addError(6, "Identifier 'test_me' is not in camel case.")
.addError(13, "Identifier 'test_1' is not in camel case.")
- .test(source, { camelcase: true });
+ .test(source, { es3: true, camelcase: true });
test.done();
@@ -239,17 +239,17 @@ exports.curly = function (test) {
src1 = fs.readFileSync(__dirname + '/fixtures/curly2.js', 'utf8');
// By default, tolerate one-line blocks since they are valid JavaScript
- TestRun(test).test(src);
- TestRun(test).test(src1);
+ TestRun(test).test(src, {es3: true});
+ TestRun(test).test(src1, {es3: true});
// Require all blocks to be wrapped with curly braces if curly is true
TestRun(test)
.addError(2, "Expected '{' and instead saw 'return'.")
.addError(5, "Expected '{' and instead saw 'doSomething'.")
.addError(8, "Expected '{' and instead saw 'doSomething'.")
- .test(src, { curly: true });
+ .test(src, { es3: true, curly: true });
- TestRun(test).test(src1, { curly: true });
+ TestRun(test).test(src1, { es3: true, curly: true });
test.done();
};
@@ -259,12 +259,12 @@ exports.noempty = function (test) {
var code = 'for (;;) {}';
// By default, tolerate empty blocks since they are valid JavaScript
- TestRun(test).test(code);
+ TestRun(test).test(code, { es3: true });
// Do not tolerate, when noempty is true
TestRun(test)
.addError(1, 'Empty block.')
- .test(code, { noempty: true });
+ .test(code, { es3: true, noempty: true });
test.done();
};
@@ -280,13 +280,13 @@ exports.noarg = function (test) {
var src = fs.readFileSync(__dirname + '/fixtures/noarg.js', 'utf8');
// By default, tolerate both arguments.callee and arguments.caller
- TestRun(test).test(src);
+ TestRun(test).test(src, { es3: true });
// Do not tolerate both .callee and .caller when noarg is true
TestRun(test)
.addError(2, 'Avoid arguments.callee.')
.addError(6, 'Avoid arguments.caller.')
- .test(src, { noarg: true });
+ .test(src, { es3: true, noarg: true });
test.done();
};
@@ -296,14 +296,14 @@ exports.nonew = function (test) {
var code = "new Thing();",
code1 = "var obj = new Thing();";
- TestRun(test).test(code);
- TestRun(test).test(code1);
+ TestRun(test).test(code, { es3: true });
+ TestRun(test).test(code1, { es3: true });
TestRun(test)
.addError(1, "Do not use 'new' for side effects.", {
character: 1
})
- .test(code, { nonew: true });
+ .test(code, { es3: true, nonew: true });
test.done();
};
@@ -334,13 +334,13 @@ exports.asi = function (test) {
.addError(26, "Missing semicolon.", { character: 10 })
.addError(27, "Missing semicolon.", { character: 12 })
.addError(28, "Missing semicolon.", { character: 12 })
- .test(src);
+ .test(src, { es3: true });
TestRun(test, 2)
.addError(2, "Missing semicolon.") // throw on "use strict", even option asi is used
.addError(4, "Line breaking error 'return'.")
.addError(17, "Line breaking error 'return'.")
- .test(src, { asi: true });
+ .test(src, { es3: true, asi: true });
test.done();
};
@@ -355,18 +355,18 @@ exports.lastsemic = function (test) {
.addError(2, "Missing semicolon.") // missing semicolon in the middle of a block
.addError(4, "Missing semicolon.") // missing semicolon in a one-liner function
.addError(5, "Missing semicolon.") // missing semicolon at the end of a block
- .test(src);
+ .test(src, {es3: true});
// with lastsemic
TestRun(test)
.addError(2, "Missing semicolon.")
.addError(5, "Missing semicolon.")
- .test(src, { lastsemic: true });
+ .test(src, { es3: true, lastsemic: true });
// this line is valid now: [1, 2, 3].forEach(function(i) { print(i) });
// line 5 isn't, because the block doesn't close on the same line
// it shouldn't interfere with asi option
- TestRun(test).test(src, { lastsemic: true, asi: true });
+ TestRun(test).test(src, { es3: true, lastsemic: true, asi: true });
test.done();
};
@@ -391,11 +391,11 @@ exports.expr = function (test) {
for (var i = 0, exp; exp = exps[i]; i += 1) {
TestRun(test)
.addError(1, 'Expected an assignment or function call and instead saw an expression.')
- .test(exp);
+ .test(exp, { es3: true });
}
for (i = 0, exp = null; exp = exps[i]; i += 1) {
- TestRun(test).test(exp, { expr: true });
+ TestRun(test).test(exp, { es3: true, expr: true });
}
test.done();
@@ -406,7 +406,7 @@ exports.undef = function (test) {
var src = fs.readFileSync(__dirname + '/fixtures/undef.js', 'utf8');
// Make sure there are no other errors
- TestRun(test).test(src);
+ TestRun(test).test(src, { es3: true });
// Make sure it fails when undef is true
TestRun(test)
@@ -420,7 +420,7 @@ exports.undef = function (test) {
.addError(19, "'localUndef' is not defined.")
.addError(21, "'localUndef' is not defined.")
.addError(22, "'localUndef' is not defined.")
- .test(src, { undef: true });
+ .test(src, { es3: true, undef: true });
// Regression test for GH-668.
src = fs.readFileSync(__dirname + "/fixtures/gh668.js", "utf8");
@@ -436,7 +436,7 @@ exports.undef = function (test) {
exports.unused = function (test) {
var src = fs.readFileSync(__dirname + '/fixtures/unused.js', 'utf8');
- TestRun(test).test(src);
+ TestRun(test).test(src, { es3: true });
var var_errors = [
[1, "'a' is defined but never used."],
@@ -447,14 +447,14 @@ exports.unused = function (test) {
var last_param_errors = [[6, "'f' is defined but never used."]];
var all_param_errors = [[15, "'err' is defined but never used."]];
- var true_run = TestRun(test);
+ var true_run = TestRun(test, {es3: true});
var_errors.concat(last_param_errors).forEach(function (e) {
true_run.addError.apply(true_run, e);
});
true_run.test(src, { unused: true });
- test.ok(!JSHINT(src, { unused: true }));
+ test.ok(!JSHINT(src, { es3: true, unused: true }));
// Test checking all function params via unused="strict"
var all_run = TestRun(test);
@@ -462,12 +462,12 @@ exports.unused = function (test) {
all_run.addError.apply(true_run, e);
});
- all_run.test(src, {unused: "strict"});
+ all_run.test(src, { es3: true, unused: "strict"});
// Test checking everything except function params
var vars_run = TestRun(test);
var_errors.forEach(function (e) { vars_run.addError.apply(vars_run, e); });
- vars_run.test(src, {unused: "vars"});
+ vars_run.test(src, { unused: "vars"});
var unused = JSHINT.data().unused;
test.equal(6, unused.length);
@@ -484,33 +484,33 @@ exports['unused overrides'] = function (test) {
var code;
code = ['function foo(a) {', '/*jshint unused:false */', '}', 'foo();'];
- TestRun(test).test(code, {unused: true});
+ TestRun(test).test(code, {es3: true, unused: true});
code = ['function foo(a, b) {', '/*jshint unused:vars */', 'var i = 3;', '}', 'foo();'];
TestRun(test)
.addError(3, "'i' is defined but never used.")
- .test(code, {unused: true});
+ .test(code, {es3: true, unused: true});
code = ['function foo(a, b) {', '/*jshint unused:true */', 'var i = 3;', '}', 'foo();'];
TestRun(test)
.addError(1, "'b' is defined but never used.")
.addError(3, "'i' is defined but never used.")
- .test(code, {unused: "strict"});
+ .test(code, {es3: true, unused: "strict"});
code = ['function foo(a, b) {', '/*jshint unused:strict */', 'var i = 3;', '}', 'foo();'];
TestRun(test)
.addError(1, "'a' is defined but never used.")
.addError(1, "'b' is defined but never used.")
.addError(3, "'i' is defined but never used.")
- .test(code, {unused: true});
+ .test(code, {es3: true, unused: true});
code = ['/*jshint unused:vars */', 'function foo(a, b) {}', 'foo();'];
- TestRun(test).test(code, {unused: "strict"});
+ TestRun(test).test(code, {es3: true, unused: "strict"});
code = ['/*jshint unused:vars */', 'function foo(a, b) {', 'var i = 3;', '}', 'foo();'];
TestRun(test)
.addError(3, "'i' is defined but never used.")
- .test(code, {unused: "strict"});
+ .test(code, {es3: true, unused: "strict"});
test.done();
};
@@ -520,8 +520,8 @@ exports['undef in a function scope'] = function (test) {
var src = fixture('undef_func.js');
// Make sure that the lint is clean with and without undef.
- TestRun(test).test(src);
- TestRun(test).test(src, { undef: true });
+ TestRun(test).test(src, {es3: true});
+ TestRun(test).test(src, {es3: true, undef: true });
test.done();
};
@@ -539,20 +539,20 @@ exports.scripturl = function (test) {
.addError(1, "Script URL.")
.addError(2, "Script URL.") // 2 times?
.addError(2, "JavaScript URL.")
- .test(code);
+ .test(code