Comparing version 2.10.2 to 2.10.3
{ | ||
"name": "jshint", | ||
"version": "2.10.2", | ||
"version": "2.10.3", | ||
"homepage": "http://jshint.com/", | ||
@@ -66,3 +66,3 @@ "description": "Static analysis tool for JavaScript", | ||
"sinon": "1.12.x", | ||
"test262-stream": "~1.2.0", | ||
"test262-stream": "~1.2.1", | ||
"unicode-5.2.0": "^0.7.5", | ||
@@ -69,0 +69,0 @@ "unicode-11.0.0": "0.7.x" |
@@ -1428,2 +1428,14 @@ /* | ||
); | ||
} else if (char === "0" && reg.decimalDigit.test(this.peek(index + 1))) { | ||
this.triggerAsync( | ||
"error", | ||
{ | ||
code: "E016", | ||
line: this.line, | ||
character: this.char, | ||
data: [ "Invalid decimal escape sequence" ] | ||
}, | ||
checks, | ||
hasUFlag | ||
); | ||
} | ||
@@ -1704,2 +1716,4 @@ | ||
escapedChar === "/" || | ||
escapedChar === "0" || | ||
reg.regexpControlEscapes.test(escapedChar) || | ||
reg.regexpCharClasses.test(escapedChar) || | ||
@@ -1706,0 +1720,0 @@ reg.regexpSyntaxChars.test(escapedChar); |
@@ -52,2 +52,4 @@ /* | ||
exports.regexpControlEscapes = /[fnrtv]/; | ||
exports.regexpCharClasses = /[dDsSwW]/; | ||
@@ -54,0 +56,0 @@ |
@@ -13,18 +13,12 @@ "use strict"; | ||
* A factory function for creating scope managers. A scope manager tracks | ||
* variables and JSHint "labels", detecting when variables are referenced | ||
* (through "usages"). | ||
* bindings, detecting when variables are referenced (through "usages"). | ||
* | ||
* Note that in this context, the term "label" describes an implementation | ||
* detail of JSHint and is not related to the ECMAScript language construct of | ||
* the same name. Where possible, the former is referred to as a "JSHint label" | ||
* to avoid confusion. | ||
* | ||
* @param {object} state - the global state object (see `state.js`) | ||
* @param {Array} predefined - a set of JSHint label names for built-in | ||
* bindings provided by the environment | ||
* @param {object} exported - a hash for JSHint label names that are intended | ||
* to be referenced in contexts beyond the current | ||
* program code | ||
* @param {object} declared - a hash for JSHint label names that were defined | ||
* as global bindings via linting configuration | ||
* @param {Array} predefined - a set of binding names for built-in bindings | ||
* provided by the environment | ||
* @param {object} exported - a hash for binding names that are intended to be | ||
* referenced in contexts beyond the current program | ||
* code | ||
* @param {object} declared - a hash for binding names that were defined as | ||
* global bindings via linting configuration | ||
* | ||
@@ -40,5 +34,5 @@ * @returns {object} - a scope manager | ||
_current = { | ||
"(bindings)": Object.create(null), | ||
"(usages)": Object.create(null), | ||
"(labels)": Object.create(null), | ||
"(usages)": Object.create(null), | ||
"(breakLabels)": Object.create(null), | ||
"(parent)": _current, | ||
@@ -77,5 +71,5 @@ "(type)": type, | ||
function _setupUsages(labelName) { | ||
if (!_current["(usages)"][labelName]) { | ||
_current["(usages)"][labelName] = { | ||
function _setupUsages(bindingName) { | ||
if (!_current["(usages)"][bindingName]) { | ||
_current["(usages)"][bindingName] = { | ||
"(modified)": [], | ||
@@ -139,7 +133,7 @@ "(reassigned)": [], | ||
} | ||
var curentLabels = _current["(labels)"]; | ||
for (var labelName in curentLabels) { | ||
if (curentLabels[labelName]["(type)"] !== "exception" && | ||
curentLabels[labelName]["(unused)"]) { | ||
_warnUnused(labelName, curentLabels[labelName]["(token)"], "var"); | ||
var currentBindings = _current["(bindings)"]; | ||
for (var bindingName in currentBindings) { | ||
if (currentBindings[bindingName]["(type)"] !== "exception" && | ||
currentBindings[bindingName]["(unused)"]) { | ||
_warnUnused(bindingName, currentBindings[bindingName]["(token)"], "var"); | ||
} | ||
@@ -158,2 +152,3 @@ } | ||
if (!params) { | ||
/* istanbul ignore next */ | ||
return; | ||
@@ -166,3 +161,3 @@ } | ||
while (param) { | ||
var label = _current["(labels)"][param]; | ||
var binding = _current["(bindings)"][param]; | ||
@@ -180,4 +175,4 @@ unused_opt = _getUnusedOption(state.funct["(unusedOption)"]); | ||
if (label["(unused)"]) { | ||
_warnUnused(param, label["(token)"], "param", state.funct["(unusedOption)"]); | ||
if (binding["(unused)"]) { | ||
_warnUnused(param, binding["(token)"], "param", state.funct["(unusedOption)"]); | ||
} else if (unused_opt === "last-param") { | ||
@@ -192,15 +187,15 @@ return; | ||
/** | ||
* Find the relevant JSHint label's scope. The owning scope is located by | ||
* first inspecting the current scope and then moving "downward" through the | ||
* stack of scopes. | ||
* Find the relevant binding's scope. The owning scope is located by first | ||
* inspecting the current scope and then moving "downward" through the stack | ||
* of scopes. | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* | ||
* @returns {Object} - the scope in which the JSHint label was found | ||
* @returns {Object} - the scope in which the binding was found | ||
*/ | ||
function _getLabel(labelName) { | ||
function _getBinding(bindingName) { | ||
for (var i = _scopeStack.length - 1 ; i >= 0; --i) { | ||
var scopeLabels = _scopeStack[i]["(labels)"]; | ||
if (scopeLabels[labelName]) { | ||
return scopeLabels; | ||
var scopeBindings = _scopeStack[i]["(bindings)"]; | ||
if (scopeBindings[bindingName]) { | ||
return scopeBindings; | ||
} | ||
@@ -211,14 +206,14 @@ } | ||
/** | ||
* Determine if a given JSHint label name has been referenced within the | ||
* current function or any function defined within. | ||
* Determine if a given binding name has been referenced within the current | ||
* function or any function defined within. | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* | ||
* @returns {boolean} | ||
*/ | ||
function usedSoFarInCurrentFunction(labelName) { | ||
function usedSoFarInCurrentFunction(bindingName) { | ||
for (var i = _scopeStack.length - 1; i >= 0; i--) { | ||
var current = _scopeStack[i]; | ||
if (current["(usages)"][labelName]) { | ||
return current["(usages)"][labelName]; | ||
if (current["(usages)"][bindingName]) { | ||
return current["(usages)"][bindingName]; | ||
} | ||
@@ -232,3 +227,3 @@ if (current === _currentFunctBody) { | ||
function _checkOuterShadow(labelName, token) { | ||
function _checkOuterShadow(bindingName, token) { | ||
@@ -250,7 +245,7 @@ // only check if shadow is outer | ||
} | ||
if (outsideCurrentFunction && stackItem["(labels)"][labelName]) { | ||
warning("W123", token, labelName); | ||
if (outsideCurrentFunction && stackItem["(bindings)"][bindingName]) { | ||
warning("W123", token, bindingName); | ||
} | ||
if (stackItem["(breakLabels)"][labelName]) { | ||
warning("W123", token, labelName); | ||
if (stackItem["(labels)"][bindingName]) { | ||
warning("W123", token, bindingName); | ||
} | ||
@@ -260,3 +255,3 @@ } | ||
function _latedefWarning(type, labelName, token) { | ||
function _latedefWarning(type, bindingName, token) { | ||
var isFunction; | ||
@@ -271,3 +266,3 @@ | ||
if ((state.option.latedef === true && isFunction) || !isFunction) { | ||
warning("W003", token, labelName); | ||
warning("W003", token, bindingName); | ||
} | ||
@@ -285,4 +280,4 @@ } | ||
isPredefined: function(labelName) { | ||
return !this.has(labelName) && _.has(_scopeStack[0]["(predefined)"], labelName); | ||
isPredefined: function(bindingName) { | ||
return !this.has(bindingName) && _.has(_scopeStack[0]["(predefined)"], bindingName); | ||
}, | ||
@@ -323,25 +318,25 @@ | ||
var currentUsages = _current["(usages)"]; | ||
var currentLabels = _current["(labels)"]; | ||
var usedLabelNameList = Object.keys(currentUsages); | ||
var currentBindings = _current["(bindings)"]; | ||
var usedBindingNameList = Object.keys(currentUsages); | ||
/* istanbul ignore if */ | ||
if (currentUsages.__proto__ && usedLabelNameList.indexOf("__proto__") === -1) { | ||
usedLabelNameList.push("__proto__"); | ||
if (currentUsages.__proto__ && usedBindingNameList.indexOf("__proto__") === -1) { | ||
usedBindingNameList.push("__proto__"); | ||
} | ||
for (i = 0; i < usedLabelNameList.length; i++) { | ||
var usedLabelName = usedLabelNameList[i]; | ||
for (i = 0; i < usedBindingNameList.length; i++) { | ||
var usedBindingName = usedBindingNameList[i]; | ||
var usage = currentUsages[usedLabelName]; | ||
var usedLabel = currentLabels[usedLabelName]; | ||
if (usedLabel) { | ||
var usedLabelType = usedLabel["(type)"]; | ||
isImmutable = usedLabelType === "const" || usedLabelType === "import"; | ||
var usage = currentUsages[usedBindingName]; | ||
var usedBinding = currentBindings[usedBindingName]; | ||
if (usedBinding) { | ||
var usedBindingType = usedBinding["(type)"]; | ||
isImmutable = usedBindingType === "const" || usedBindingType === "import"; | ||
if (usedLabel["(useOutsideOfScope)"] && !state.option.funcscope) { | ||
if (usedBinding["(useOutsideOfScope)"] && !state.option.funcscope) { | ||
var usedTokens = usage["(tokens)"]; | ||
for (j = 0; j < usedTokens.length; j++) { | ||
// Keep the consistency of https://github.com/jshint/jshint/issues/2409 | ||
if (usedLabel["(function)"] === usedTokens[j]["(function)"]) { | ||
error("W038", usedTokens[j], usedLabelName); | ||
if (usedBinding["(function)"] === usedTokens[j]["(function)"]) { | ||
error("W038", usedTokens[j], usedBindingName); | ||
} | ||
@@ -351,4 +346,4 @@ } | ||
// mark the label used | ||
_current["(labels)"][usedLabelName]["(unused)"] = false; | ||
// mark the binding used | ||
_current["(bindings)"][usedBindingName]["(unused)"] = false; | ||
@@ -358,15 +353,15 @@ // check for modifying a const | ||
for (j = 0; j < usage["(modified)"].length; j++) { | ||
error("E013", usage["(modified)"][j], usedLabelName); | ||
error("E013", usage["(modified)"][j], usedBindingName); | ||
} | ||
} | ||
isFunction = usedLabelType === "function" || | ||
usedLabelType === "generator function" || | ||
usedLabelType === "async function"; | ||
isFunction = usedBindingType === "function" || | ||
usedBindingType === "generator function" || | ||
usedBindingType === "async function"; | ||
// check for re-assigning a function declaration | ||
if ((isFunction || usedLabelType === "class") && usage["(reassigned)"]) { | ||
if ((isFunction || usedBindingType === "class") && usage["(reassigned)"]) { | ||
for (j = 0; j < usage["(reassigned)"].length; j++) { | ||
if (!usage["(reassigned)"][j].ignoreW021) { | ||
warning("W021", usage["(reassigned)"][j], usedLabelName, usedLabelType); | ||
warning("W021", usage["(reassigned)"][j], usedBindingName, usedBindingType); | ||
} | ||
@@ -379,5 +374,5 @@ } | ||
if (subScope) { | ||
var labelType = this.labeltype(usedLabelName); | ||
isImmutable = labelType === "const" || | ||
(labelType === null && _scopeStack[0]["(predefined)"][usedLabelName] === false); | ||
var bindingType = this.bindingtype(usedBindingName); | ||
isImmutable = bindingType === "const" || | ||
(bindingType === null && _scopeStack[0]["(predefined)"][usedBindingName] === false); | ||
if (isUnstackingFunctionOuter && !isImmutable) { | ||
@@ -387,13 +382,13 @@ if (!state.funct["(outerMutables)"]) { | ||
} | ||
state.funct["(outerMutables)"].push(usedLabelName); | ||
state.funct["(outerMutables)"].push(usedBindingName); | ||
} | ||
// not exiting the global scope, so copy the usage down in case its an out of scope usage | ||
if (!subScope["(usages)"][usedLabelName]) { | ||
subScope["(usages)"][usedLabelName] = usage; | ||
if (!subScope["(usages)"][usedBindingName]) { | ||
subScope["(usages)"][usedBindingName] = usage; | ||
if (isUnstackingFunctionBody) { | ||
subScope["(usages)"][usedLabelName]["(onlyUsedSubFunction)"] = true; | ||
subScope["(usages)"][usedBindingName]["(onlyUsedSubFunction)"] = true; | ||
} | ||
} else { | ||
var subScopeUsage = subScope["(usages)"][usedLabelName]; | ||
var subScopeUsage = subScope["(usages)"][usedBindingName]; | ||
subScopeUsage["(modified)"] = subScopeUsage["(modified)"].concat(usage["(modified)"]); | ||
@@ -406,12 +401,12 @@ subScopeUsage["(tokens)"] = subScopeUsage["(tokens)"].concat(usage["(tokens)"]); | ||
// this is exiting global scope, so we finalise everything here - we are at the end of the file | ||
if (typeof _current["(predefined)"][usedLabelName] === "boolean") { | ||
if (typeof _current["(predefined)"][usedBindingName] === "boolean") { | ||
// remove the declared token, so we know it is used | ||
delete declared[usedLabelName]; | ||
delete declared[usedBindingName]; | ||
// note it as used so it can be reported | ||
usedPredefinedAndGlobals[usedLabelName] = marker; | ||
usedPredefinedAndGlobals[usedBindingName] = marker; | ||
// check for re-assigning a read-only (set to false) predefined | ||
if (_current["(predefined)"][usedLabelName] === false && usage["(reassigned)"]) { | ||
if (_current["(predefined)"][usedBindingName] === false && usage["(reassigned)"]) { | ||
for (j = 0; j < usage["(reassigned)"].length; j++) { | ||
@@ -425,3 +420,3 @@ if (!usage["(reassigned)"][j].ignoreW020) { | ||
else { | ||
// label usage is not predefined and we have not found a declaration | ||
// binding usage is not predefined and we have not found a declaration | ||
// so report as undeclared | ||
@@ -434,9 +429,9 @@ for (j = 0; j < usage["(tokens)"].length; j++) { | ||
if (state.option.undef && !undefinedToken.ignoreUndef) { | ||
warning("W117", undefinedToken, usedLabelName); | ||
warning("W117", undefinedToken, usedBindingName); | ||
} | ||
if (impliedGlobals[usedLabelName]) { | ||
impliedGlobals[usedLabelName].line.push(undefinedToken.line); | ||
if (impliedGlobals[usedBindingName]) { | ||
impliedGlobals[usedBindingName].line.push(undefinedToken.line); | ||
} else { | ||
impliedGlobals[usedLabelName] = { | ||
name: usedLabelName, | ||
impliedGlobals[usedBindingName] = { | ||
name: usedBindingName, | ||
line: [undefinedToken.line] | ||
@@ -454,22 +449,23 @@ }; | ||
Object.keys(declared) | ||
.forEach(function(labelNotUsed) { | ||
_warnUnused(labelNotUsed, declared[labelNotUsed], "var"); | ||
.forEach(function(bindingNotUsed) { | ||
_warnUnused(bindingNotUsed, declared[bindingNotUsed], "var"); | ||
}); | ||
} | ||
// If this is not a function boundary, transfer function-scoped labels to | ||
// If this is not a function boundary, transfer function-scoped bindings to | ||
// the parent block (a rough simulation of variable hoisting). Previously | ||
// existing labels in the parent block should take precedence so that things and stuff. | ||
// existing bindings in the parent block should take precedence so that | ||
// prior usages are not discarded. | ||
if (subScope && !isUnstackingFunctionBody && | ||
!isUnstackingFunctionParams && !isUnstackingFunctionOuter) { | ||
var labelNames = Object.keys(currentLabels); | ||
for (i = 0; i < labelNames.length; i++) { | ||
var bindingNames = Object.keys(currentBindings); | ||
for (i = 0; i < bindingNames.length; i++) { | ||
var defLabelName = labelNames[i]; | ||
var defLabel = currentLabels[defLabelName]; | ||
var defBindingName = bindingNames[i]; | ||
var defBinding = currentBindings[defBindingName]; | ||
if (!defLabel["(blockscoped)"] && defLabel["(type)"] !== "exception") { | ||
var shadowed = subScope["(labels)"][defLabelName]; | ||
if (!defBinding["(blockscoped)"] && defBinding["(type)"] !== "exception") { | ||
var shadowed = subScope["(bindings)"][defBindingName]; | ||
// Do not overwrite a label if it exists in the parent scope | ||
// Do not overwrite a binding if it exists in the parent scope | ||
// because it is shared by adjacent blocks. Copy the `unused` | ||
@@ -479,5 +475,5 @@ // property so that any references found within the current block | ||
if (shadowed) { | ||
shadowed["(unused)"] &= defLabel["(unused)"]; | ||
shadowed["(unused)"] &= defBinding["(unused)"]; | ||
// "Hoist" the variable to the parent block, decorating the label | ||
// "Hoist" the variable to the parent block, decorating the binding | ||
// so that future references, though technically valid, can be | ||
@@ -487,14 +483,14 @@ // reported as "out-of-scope" in the absence of the `funcscope` | ||
} else { | ||
defLabel["(useOutsideOfScope)"] = | ||
defBinding["(useOutsideOfScope)"] = | ||
// Do not warn about out-of-scope usages in the global scope | ||
_currentFunctBody["(type)"] !== "global" && | ||
// When a higher scope contains a binding for the label, the | ||
// label is a re-declaration and should not prompt "used | ||
// When a higher scope contains a binding for the binding, the | ||
// binding is a re-declaration and should not prompt "used | ||
// out-of-scope" warnings. | ||
!this.funct.has(defLabelName, { excludeCurrent: true }); | ||
!this.funct.has(defBindingName, { excludeCurrent: true }); | ||
subScope["(labels)"][defLabelName] = defLabel; | ||
subScope["(bindings)"][defBindingName] = defBinding; | ||
} | ||
delete currentLabels[defLabelName]; | ||
delete currentBindings[defBindingName]; | ||
} | ||
@@ -520,7 +516,7 @@ } | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {Token} token | ||
* @param {string} [type] - JSHint label type; defaults to "param" | ||
* @param {string} [type] - binding type; defaults to "param" | ||
*/ | ||
addParam: function(labelName, token, type) { | ||
addParam: function(bindingName, token, type) { | ||
type = type || "param"; | ||
@@ -530,11 +526,11 @@ | ||
// if defined in the current function | ||
var previouslyDefinedLabelType = this.funct.labeltype(labelName); | ||
if (previouslyDefinedLabelType && previouslyDefinedLabelType !== "exception") { | ||
var previouslyDefinedBindingType = this.funct.bindingtype(bindingName); | ||
if (previouslyDefinedBindingType && previouslyDefinedBindingType !== "exception") { | ||
// and has not been used yet in the current function scope | ||
if (!state.option.node) { | ||
warning("W002", state.tokens.next, labelName); | ||
warning("W002", state.tokens.next, bindingName); | ||
} | ||
} | ||
if (state.isStrict() && (labelName === "arguments" || labelName === "eval")) { | ||
if (state.isStrict() && (bindingName === "arguments" || bindingName === "eval")) { | ||
warning("E008", token); | ||
@@ -545,4 +541,4 @@ } | ||
// The variable was declared in the current scope | ||
if (_.has(_current["(labels)"], labelName)) { | ||
_current["(labels)"][labelName].duplicated = true; | ||
if (_.has(_current["(bindings)"], bindingName)) { | ||
_current["(bindings)"][bindingName].duplicated = true; | ||
@@ -552,5 +548,5 @@ // The variable was declared in an outer scope | ||
// if this scope has the variable defined, it's a re-definition error | ||
_checkOuterShadow(labelName, token); | ||
_checkOuterShadow(bindingName, token); | ||
_current["(labels)"][labelName] = { | ||
_current["(bindings)"][bindingName] = { | ||
"(type)" : type, | ||
@@ -560,13 +556,13 @@ "(token)": token, | ||
_current["(params)"].push(labelName); | ||
_current["(params)"].push(bindingName); | ||
} | ||
if (_.has(_current["(usages)"], labelName)) { | ||
var usage = _current["(usages)"][labelName]; | ||
if (_.has(_current["(usages)"], bindingName)) { | ||
var usage = _current["(usages)"][bindingName]; | ||
// if its in a sub function it is not necessarily an error, just latedef | ||
if (usage["(onlyUsedSubFunction)"]) { | ||
_latedefWarning(type, labelName, token); | ||
_latedefWarning(type, bindingName, token); | ||
} else { | ||
// this is a clear illegal usage for block scoped variables | ||
warning("E056", token, labelName, type); | ||
warning("E056", token, bindingName, type); | ||
} | ||
@@ -594,18 +590,19 @@ } | ||
if (!currentFunctParamScope["(params)"]) { | ||
/* istanbul ignore next */ | ||
return; | ||
} | ||
currentFunctParamScope["(params)"].forEach(function(labelName) { | ||
var label = currentFunctParamScope["(labels)"][labelName]; | ||
currentFunctParamScope["(params)"].forEach(function(bindingName) { | ||
var binding = currentFunctParamScope["(bindings)"][bindingName]; | ||
if (label.duplicated) { | ||
if (binding.duplicated) { | ||
if (isStrict || isArrow || isMethod || !isSimple) { | ||
warning("E011", label["(token)"], labelName); | ||
warning("E011", binding["(token)"], bindingName); | ||
} else if (state.option.shadow !== true) { | ||
warning("W004", label["(token)"], labelName); | ||
warning("W004", binding["(token)"], bindingName); | ||
} | ||
} | ||
if (isStrict && (labelName === "arguments" || labelName === "eval")) { | ||
warning("E008", label["(token)"]); | ||
if (isStrict && (bindingName === "arguments" || bindingName === "eval")) { | ||
warning("E008", binding["(token)"]); | ||
} | ||
@@ -671,22 +668,22 @@ }); | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* | ||
* @return {boolean} | ||
*/ | ||
has: function(labelName) { | ||
return Boolean(_getLabel(labelName)); | ||
has: function(bindingName) { | ||
return Boolean(_getBinding(bindingName)); | ||
}, | ||
/** | ||
* Retrieve described by `labelName` or null | ||
* Retrieve binding described by `bindingName` or null | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* | ||
* @returns {string|null} - the type of the JSHint label or `null` if no | ||
* such label exists | ||
* @returns {string|null} - the type of the binding or `null` if no such | ||
* binding exists | ||
*/ | ||
labeltype: function(labelName) { | ||
var scopeLabels = _getLabel(labelName); | ||
if (scopeLabels) { | ||
return scopeLabels[labelName]["(type)"]; | ||
bindingtype: function(bindingName) { | ||
var scopeBindings = _getBinding(bindingName); | ||
if (scopeBindings) { | ||
return scopeBindings[bindingName]["(type)"]; | ||
} | ||
@@ -699,11 +696,11 @@ return null; | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
*/ | ||
addExported: function(labelName) { | ||
var globalLabels = _scopeStack[0]["(labels)"]; | ||
if (_.has(declared, labelName)) { | ||
addExported: function(bindingName) { | ||
var globalBindings = _scopeStack[0]["(bindings)"]; | ||
if (_.has(declared, bindingName)) { | ||
// remove the declared token, so we know it is used | ||
delete declared[labelName]; | ||
} else if (_.has(globalLabels, labelName)) { | ||
globalLabels[labelName]["(unused)"] = false; | ||
delete declared[bindingName]; | ||
} else if (_.has(globalBindings, bindingName)) { | ||
globalBindings[bindingName]["(unused)"] = false; | ||
} else { | ||
@@ -714,12 +711,13 @@ for (var i = 1; i < _scopeStack.length; i++) { | ||
if (!scope["(type)"]) { | ||
if (_.has(scope["(labels)"], labelName) && | ||
!scope["(labels)"][labelName]["(blockscoped)"]) { | ||
scope["(labels)"][labelName]["(unused)"] = false; | ||
if (_.has(scope["(bindings)"], bindingName) && | ||
!scope["(bindings)"][bindingName]["(blockscoped)"]) { | ||
scope["(bindings)"][bindingName]["(unused)"] = false; | ||
return; | ||
} | ||
} else { | ||
/* istanbul ignore next */ | ||
break; | ||
} | ||
} | ||
exported[labelName] = true; | ||
exported[bindingName] = true; | ||
} | ||
@@ -729,21 +727,21 @@ }, | ||
/** | ||
* Mark a JSHint label as "exported" by an ES2015 module | ||
* Mark a binding as "exported" by an ES2015 module | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {object} token | ||
*/ | ||
setExported: function(labelName, token) { | ||
this.block.use(labelName, token); | ||
setExported: function(bindingName, token) { | ||
this.block.use(bindingName, token); | ||
}, | ||
/** | ||
* Mark a JSHint label as "initialized." This is necessary to enforce the | ||
* Mark a binding as "initialized." This is necessary to enforce the | ||
* "temporal dead zone" (TDZ) of block-scoped bindings which are not | ||
* hoisted. | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
*/ | ||
initialize: function(labelName) { | ||
if (_current["(labels)"][labelName]) { | ||
_current["(labels)"][labelName]["(initialized)"] = true; | ||
initialize: function(bindingName) { | ||
if (_current["(bindings)"][bindingName]) { | ||
_current["(bindings)"][bindingName]["(initialized)"] = true; | ||
} | ||
@@ -753,9 +751,9 @@ }, | ||
/** | ||
* Create a new JSHint label and add it to the current scope. Delegates to | ||
* the internal `block.add` or `func.add` methods depending on the type. | ||
* Create a new binding and add it to the current scope. Delegates to the | ||
* internal `block.add` or `func.add` methods depending on the type. | ||
* Produces warnings and errors as necessary. | ||
* | ||
* @param {string} labelName | ||
* @param {string} bindingName | ||
* @param {Object} opts | ||
* @param {String} opts.type - the type of the label e.g. "param", "var", | ||
* @param {String} opts.type - the type of the binding e.g. "param", "var", | ||
* "let, "const", "import", "function", | ||
@@ -768,3 +766,3 @@ * "generator function", "async function", | ||
*/ | ||
addlabel: function(labelName, opts) { | ||
addbinding: function(bindingName, opts) { | ||
@@ -779,8 +777,8 @@ var type = opts.type; | ||
var isexported = (isblockscoped ? _current : _currentFunctBody)["(type)"] === "global" && | ||
_.has(exported, labelName); | ||
_.has(exported, bindingName); | ||
// outer shadow check (inner is only on non-block scoped) | ||
_checkOuterShadow(labelName, token); | ||
_checkOuterShadow(bindingName, token); | ||
if (state.isStrict() && (labelName === "arguments" || labelName === "eval")) { | ||
if (state.isStrict() && (bindingName === "arguments" || bindingName === "eval")) { | ||
warning("E008", token); | ||
@@ -791,3 +789,3 @@ } | ||
var declaredInCurrentScope = _current["(labels)"][labelName]; | ||
var declaredInCurrentScope = _current["(bindings)"][bindingName]; | ||
// for block scoped variables, params are seen in the current scope as the root function | ||
@@ -797,14 +795,14 @@ // scope, so check these too. | ||
_current["(type)"] !== "global") { | ||
declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(labels)"][labelName]; | ||
declaredInCurrentScope = !!_currentFunctBody["(parent)"]["(bindings)"][bindingName]; | ||
} | ||
// if its not already defined (which is an error, so ignore) and is used in TDZ | ||
if (!declaredInCurrentScope && _current["(usages)"][labelName]) { | ||
var usage = _current["(usages)"][labelName]; | ||
if (!declaredInCurrentScope && _current["(usages)"][bindingName]) { | ||
var usage = _current["(usages)"][bindingName]; | ||
// if its in a sub function it is not necessarily an error, just latedef | ||
if (usage["(onlyUsedSubFunction)"] || ishoisted) { | ||
_latedefWarning(type, labelName, token); | ||
_latedefWarning(type, bindingName, token); | ||
} else if (!ishoisted) { | ||
// this is a clear illegal usage for block scoped variables | ||
warning("E056", token, labelName, type); | ||
warning("E056", token, bindingName, type); | ||
} | ||
@@ -822,3 +820,3 @@ } | ||
(!ishoisted || (_current["(type)"] !== "global" || type === "import"))) { | ||
warning("E011", token, labelName); | ||
warning("E011", token, bindingName); | ||
} | ||
@@ -828,4 +826,4 @@ else if (state.option.shadow === "outer") { | ||
// if shadow is outer, for block scope we want to detect any shadowing within this function | ||
if (scopeManagerInst.funct.has(labelName)) { | ||
warning("W004", token, labelName); | ||
if (scopeManagerInst.funct.has(bindingName)) { | ||
warning("W004", token, bindingName); | ||
} | ||
@@ -835,3 +833,3 @@ } | ||
scopeManagerInst.block.add( | ||
labelName, type, token, !isexported, opts.initialized | ||
bindingName, type, token, !isexported, opts.initialized | ||
); | ||
@@ -841,7 +839,7 @@ | ||
var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(labelName); | ||
var declaredInCurrentFunctionScope = scopeManagerInst.funct.has(bindingName); | ||
// check for late definition, ignore if already declared | ||
if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(labelName)) { | ||
_latedefWarning(type, labelName, token); | ||
if (!declaredInCurrentFunctionScope && usedSoFarInCurrentFunction(bindingName)) { | ||
_latedefWarning(type, bindingName, token); | ||
} | ||
@@ -851,12 +849,12 @@ | ||
// is in scope is an error | ||
if (scopeManagerInst.funct.has(labelName, { onlyBlockscoped: true })) { | ||
warning("E011", token, labelName); | ||
if (scopeManagerInst.funct.has(bindingName, { onlyBlockscoped: true })) { | ||
warning("E011", token, bindingName); | ||
} else if (state.option.shadow !== true) { | ||
// now since we didn't get any block scope variables, test for var/function | ||
// shadowing | ||
if (declaredInCurrentFunctionScope && labelName !== "__proto__") { | ||
if (declaredInCurrentFunctionScope && bindingName !== "__proto__") { | ||
// see https://github.com/jshint/jshint/issues/2400 | ||
if (_currentFunctBody["(type)"] !== "global") { | ||
warning("W004", token, labelName); | ||
warning("W004", token, bindingName); | ||
} | ||
@@ -866,6 +864,6 @@ } | ||
scopeManagerInst.funct.add(labelName, type, token, !isexported); | ||
scopeManagerInst.funct.add(bindingName, type, token, !isexported); | ||
if (_currentFunctBody["(type)"] === "global" && !state.impliedClosure()) { | ||
usedPredefinedAndGlobals[labelName] = marker; | ||
usedPredefinedAndGlobals[bindingName] = marker; | ||
} | ||
@@ -877,8 +875,8 @@ } | ||
/** | ||
* Return the type of the provided JSHint label given certain options | ||
* Return the type of the provided binding given certain options | ||
* | ||
* @param {string} labelName | ||
* @param {string} bindingName | ||
* @param {Object=} [options] | ||
* @param {boolean} [options.onlyBlockscoped] - only include block scoped | ||
* labels | ||
* bindings | ||
* @param {boolean} [options.excludeParams] - exclude the param scope | ||
@@ -889,3 +887,3 @@ * @param {boolean} [options.excludeCurrent] - exclude the current scope | ||
*/ | ||
labeltype: function(labelName, options) { | ||
bindingtype: function(bindingName, options) { | ||
var onlyBlockscoped = options && options.onlyBlockscoped; | ||
@@ -896,5 +894,5 @@ var excludeParams = options && options.excludeParams; | ||
var current = _scopeStack[i]; | ||
if (current["(labels)"][labelName] && | ||
(!onlyBlockscoped || current["(labels)"][labelName]["(blockscoped)"])) { | ||
return current["(labels)"][labelName]["(type)"]; | ||
if (current["(bindings)"][bindingName] && | ||
(!onlyBlockscoped || current["(bindings)"][bindingName]["(blockscoped)"])) { | ||
return current["(bindings)"][bindingName]["(type)"]; | ||
} | ||
@@ -917,7 +915,7 @@ var scopeCheck = excludeParams ? _scopeStack[ i - 1 ] : current; | ||
*/ | ||
hasBreakLabel: function(labelName) { | ||
hasLabel: function(labelName) { | ||
for (var i = _scopeStack.length - 1; i >= 0; i--) { | ||
var current = _scopeStack[i]; | ||
if (current["(breakLabels)"][labelName]) { | ||
if (current["(labels)"][labelName]) { | ||
return true; | ||
@@ -936,26 +934,26 @@ } | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {object} options - options as supported by the | ||
* `funct.labeltype` method | ||
* `funct.bindingtype` method | ||
* | ||
* @return {boolean} | ||
*/ | ||
has: function(labelName, options) { | ||
return Boolean(this.labeltype(labelName, options)); | ||
has: function(bindingName, options) { | ||
return Boolean(this.bindingtype(bindingName, options)); | ||
}, | ||
/** | ||
* Create a new function-scoped JSHint label and add it to the current | ||
* scope. See the `block.add` method for coresponding logic to create | ||
* block-scoped JSHint labels. | ||
* Create a new function-scoped binding and add it to the current scope. | ||
* See the `block.add` method for coresponding logic to create | ||
* block-scoped bindings. | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} type - the type of the JSHint label; either "function" | ||
* or "var" | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {string} type - the type of the binding; either "function" or | ||
* "var" | ||
* @param {object} tok - the token that triggered the definition | ||
* @param {boolean} unused - `true` if the JSHint label has not been | ||
* @param {boolean} unused - `true` if the binding has not been | ||
* referenced | ||
*/ | ||
add: function(labelName, type, tok, unused) { | ||
_current["(labels)"][labelName] = { | ||
add: function(bindingName, type, tok, unused) { | ||
_current["(bindings)"][bindingName] = { | ||
"(type)" : type, | ||
@@ -981,9 +979,9 @@ "(token)": tok, | ||
/** | ||
* Resolve a reference to a binding and mark the corresponding JSHint | ||
* label as "used." | ||
* Resolve a reference to a binding and mark the corresponding binding as | ||
* "used." | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {object} token - the token value that triggered the reference | ||
*/ | ||
use: function(labelName, token) { | ||
use: function(bindingName, token) { | ||
// If the name resolves to a parameter of the current function, then do | ||
@@ -1000,9 +998,9 @@ // not store usage. This is because in cases such as the following: | ||
var paramScope = _currentFunctBody["(parent)"]; | ||
if (paramScope && paramScope["(labels)"][labelName] && | ||
paramScope["(labels)"][labelName]["(type)"] === "param") { | ||
if (paramScope && paramScope["(bindings)"][bindingName] && | ||
paramScope["(bindings)"][bindingName]["(type)"] === "param") { | ||
// then check its not declared by a block scope variable | ||
if (!scopeManagerInst.funct.has(labelName, | ||
if (!scopeManagerInst.funct.has(bindingName, | ||
{ excludeParams: true, onlyBlockscoped: true })) { | ||
paramScope["(labels)"][labelName]["(unused)"] = false; | ||
paramScope["(bindings)"][bindingName]["(unused)"] = false; | ||
} | ||
@@ -1015,9 +1013,9 @@ } | ||
_setupUsages(labelName); | ||
_setupUsages(bindingName); | ||
_current["(usages)"][labelName]["(onlyUsedSubFunction)"] = false; | ||
_current["(usages)"][bindingName]["(onlyUsedSubFunction)"] = false; | ||
if (token) { | ||
token["(function)"] = _currentFunctBody; | ||
_current["(usages)"][labelName]["(tokens)"].push(token); | ||
_current["(usages)"][bindingName]["(tokens)"].push(token); | ||
} | ||
@@ -1027,43 +1025,43 @@ | ||
// "temporal dead zone" (TDZ) restrictions. | ||
var label = _current["(labels)"][labelName]; | ||
if (label && label["(blockscoped)"] && !label["(initialized)"]) { | ||
error("E056", token, labelName, label["(type)"]); | ||
var binding = _current["(bindings)"][bindingName]; | ||
if (binding && binding["(blockscoped)"] && !binding["(initialized)"]) { | ||
error("E056", token, bindingName, binding["(type)"]); | ||
} | ||
}, | ||
reassign: function(labelName, token) { | ||
reassign: function(bindingName, token) { | ||
token.ignoreW020 = state.ignored.W020; | ||
token.ignoreW021 = state.ignored.W021; | ||
this.modify(labelName, token); | ||
this.modify(bindingName, token); | ||
_current["(usages)"][labelName]["(reassigned)"].push(token); | ||
_current["(usages)"][bindingName]["(reassigned)"].push(token); | ||
}, | ||
modify: function(labelName, token) { | ||
modify: function(bindingName, token) { | ||
_setupUsages(labelName); | ||
_setupUsages(bindingName); | ||
_current["(usages)"][labelName]["(onlyUsedSubFunction)"] = false; | ||
_current["(usages)"][labelName]["(modified)"].push(token); | ||
_current["(usages)"][bindingName]["(onlyUsedSubFunction)"] = false; | ||
_current["(usages)"][bindingName]["(modified)"].push(token); | ||
}, | ||
/** | ||
* Create a new block-scoped JSHint label and add it to the current | ||
* scope. See the `funct.add` method for coresponding logic to create | ||
* function-scoped JSHint labels. | ||
* Create a new block-scoped binding and add it to the current scope. See | ||
* the `funct.add` method for coresponding logic to create | ||
* function-scoped bindings. | ||
* | ||
* @param {string} labelName - the value of the identifier | ||
* @param {string} type - the type of the JSHint label; one of "class", | ||
* @param {string} bindingName - the value of the identifier | ||
* @param {string} type - the type of the binding; one of "class", | ||
* "const", "function", "import", or "let" | ||
* @param {object} tok - the token that triggered the definition | ||
* @param {boolean} unused - `true` if the JSHint label has not been | ||
* @param {boolean} unused - `true` if the binding has not been | ||
* referenced | ||
* @param {boolean} initialized - `true` if the JSHint label has been | ||
* initialized (as is the case with JSHint | ||
* labels created via `import` | ||
* @param {boolean} initialized - `true` if the binding has been | ||
* initialized (as is the case with | ||
* bindings created via `import` | ||
* declarations) | ||
*/ | ||
add: function(labelName, type, tok, unused, initialized) { | ||
_current["(labels)"][labelName] = { | ||
add: function(bindingName, type, tok, unused, initialized) { | ||
_current["(bindings)"][bindingName] = { | ||
"(type)" : type, | ||
@@ -1076,5 +1074,5 @@ "(token)": tok, | ||
addBreakLabel: function(labelName, opts) { | ||
addLabel: function(labelName, opts) { | ||
var token = opts.token; | ||
if (scopeManagerInst.funct.hasBreakLabel(labelName)) { | ||
if (scopeManagerInst.funct.hasLabel(labelName)) { | ||
warning("E011", token, labelName); | ||
@@ -1089,3 +1087,3 @@ } | ||
} | ||
_current["(breakLabels)"][labelName] = token; | ||
_current["(labels)"][labelName] = token; | ||
} | ||
@@ -1092,0 +1090,0 @@ } |
@@ -69,3 +69,3 @@ "use strict"; | ||
/** | ||
* Determine if constructs introduced in ECMAScript 8 should be accepted. | ||
* Determine if constructs introduced in ECMAScript 9 should be accepted. | ||
* | ||
@@ -72,0 +72,0 @@ * @returns {boolean} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 5 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3676769
39
72111
5