"use strict"; var NameStack = require("./name-stack.js"); var state = { syntax: {}, /** * Determine if the code currently being linted is strict mode code. * * @returns {boolean} */ isStrict: function() { return !!this.directive["use strict"] || this.inClassBody || this.option.module || this.option.strict === "implied"; }, /** * Determine if the current state warrants a warning for statements outside * of strict mode code. * * While emitting warnings based on function scope would be more intuitive * (and less noisy), JSHint observes statement-based semantics in order to * preserve legacy behavior. * * This method does not take the state of the parser into account, making no * distinction between global code and function code. Because the "missing * 'use strict'" warning is *also* reported at function boundaries, this * function interprets `strict` option values `true` and `undefined` as * equivalent. */ stmtMissingStrict: function() { if (this.option.strict === "global") { return true; } if (this.option.strict === false) { return false; } if (this.option.globalstrict) { return true; } return false; }, allowsGlobalUsd: function() { return this.option.strict === "global" || this.option.globalstrict || this.option.module || this.impliedClosure(); }, /** * Determine if the current configuration describes an environment that is * wrapped in an immediately-invoked function expression prior to evaluation. * * @returns {boolean} */ impliedClosure: function() { return this.option.node || this.option.phantom || this.option.browserify; }, // Assumption: chronologically ES3 < ES5 < ES6 < Moz inMoz: function() { return this.option.moz; }, /** * Determine if constructs introduced in ECMAScript 11 should be accepted. * * @returns {boolean} */ inES11: function() { return this.esVersion >= 11; }, /** * Determine if constructs introduced in ECMAScript 10 should be accepted. * * @returns {boolean} */ inES10: function() { return this.esVersion >= 10; }, /** * Determine if constructs introduced in ECMAScript 9 should be accepted. * * @returns {boolean} */ inES9: function() { return this.esVersion >= 9; }, /** * Determine if constructs introduced in ECMAScript 8 should be accepted. * * @returns {boolean} */ inES8: function() { return this.esVersion >= 8; }, /** * Determine if constructs introduced in ECMAScript 7 should be accepted. * * @returns {boolean} */ inES7: function() { return this.esVersion >= 7; }, /** * Determine if constructs introduced in ECMAScript 6 should be accepted. * * @param {boolean} strict - When `true`, do not interpret the `moz` option * as ECMAScript 6 * * @returns {boolean} */ inES6: function(strict) { if (!strict && this.option.moz) { return true; } return this.esVersion >= 6; }, /** * Determine if constructs introduced in ECMAScript 5 should be accepted. * * @returns {boolean} */ inES5: function() { return !this.esVersion || this.esVersion >= 5 || this.option.moz; }, /** * Determine the current version of the input language by inspecting the * value of all ECMAScript-version-related options. This logic is necessary * to ensure compatibility with deprecated options `es3`, `es5`, and * `esnext`, and it may be drastically simplified when those options are * removed. * * @returns {string|null} - the name of any incompatible option detected, * `null` otherwise */ inferEsVersion: function() { var badOpt = null; if (this.option.esversion) { if (this.option.es3) { badOpt = "es3"; } else if (this.option.es5) { badOpt = "es5"; } else if (this.option.esnext) { badOpt = "esnext"; } if (badOpt) { return badOpt; } if (this.option.esversion === 2015) { this.esVersion = 6; } else { this.esVersion = this.option.esversion; } } else if (this.option.es3) { this.esVersion = 3; } else if (this.option.esnext) { this.esVersion = 6; } return null; }, reset: function() { this.tokens = { prev: null, next: null, curr: null }; this.option = { unstable: {} }; this.esVersion = 5; this.funct = null; this.ignored = {}; /** * A lookup table for active directives whose keys are the value of the * directives and whose values are the tokens which enabled the directives. */ this.directive = Object.create(null); this.jsonMode = false; this.lines = []; this.tab = ""; this.cache = {}; // Node.JS doesn't have Map. Sniff. this.ignoredLines = {}; this.forinifcheckneeded = false; this.nameStack = new NameStack(); this.inClassBody = false; } }; exports.state = state;