Refactor for 2.0

This commit is contained in:
Colin McLeod
2016-01-11 18:02:23 -08:00
parent 99f024aad2
commit 464f084f71
5409 changed files with 458891 additions and 1829 deletions

20
node_modules/eslint/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
ESLint
Copyright (c) 2013 Nicholas C. Zakas. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

126
node_modules/eslint/README.md generated vendored Normal file
View File

@@ -0,0 +1,126 @@
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][coveralls-image]][coveralls-url]
[![Downloads][downloads-image]][downloads-url]
[![Bountysource](https://www.bountysource.com/badge/tracker?tracker_id=282608)](https://www.bountysource.com/trackers/282608-eslint?utm_source=282608&utm_medium=shield&utm_campaign=TRACKER_BADGE)
[![Join the chat at https://gitter.im/eslint/eslint](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/eslint/eslint?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# ESLint
[Website](http://eslint.org) | [Configuring](http://eslint.org/docs/user-guide/configuring) | [Rules](http://eslint.org/docs/rules/) | [Contributing](http://eslint.org/docs/developer-guide/contributing) | [Twitter](https://twitter.com/geteslint) | [Mailing List](https://groups.google.com/group/eslint)
ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code. In many ways, it is similar to JSLint and JSHint with a few exceptions:
* ESLint uses [Espree](https://github.com/eslint/espree) for JavaScript parsing.
* ESLint uses an AST to evaluate patterns in code.
* ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.
## Installation
You can install ESLint using npm:
npm install -g eslint
## Usage
If it's your first time using ESLint, you should set up a config file using `--init`:
eslint --init
After that, you can run ESLint on any JavaScript file:
eslint test.js test2.js
## Configuration
After running `eslint --init`, you'll have a `.eslintrc` file in your directory. In it, you'll see some rules configured like this:
```json
{
"rules": {
"semi": [2, "always"],
"quotes": [2, "double"]
}
}
```
The names `"semi"` and `"quotes"` are the names of [rules](http://eslint.org/docs/rules) in ESLint. The number is the error level of the rule and can be one of the three values:
* `0` - turn the rule off
* `1` - turn the rule on as a warning (doesn't affect exit code)
* `2` - turn the rule on as an error (exit code will be 1)
The three error levels allow you fine-grained control over how ESLint applies rules (for more configuration options and details, see the [configuration docs](http://eslint.org/docs/user-guide/configuring)).
## Sponsors
* Development is sponsored by [Box](https://box.com)
## Team
These folks keep the project moving and are resources for help:
* Nicholas C. Zakas ([@nzakas](https://github.com/nzakas)) - project lead
* Ilya Volodin ([@ilyavolodin](https://github.com/ilyavolodin)) - reviewer
* Brandon Mills ([@btmills](https://github.com/btmills)) - reviewer
* Gyandeep Singh ([@gyandeeps](https://github.com/gyandeeps)) - reviewer
* Mathias Schreck ([@lo1tuma](https://github.com/lo1tuma)) - committer
* Jamund Ferguson ([@xjamundx](https://github.com/xjamundx)) - committer
* Ian VanSchooten ([@ianvs](https://github.com/ianvs)) - committer
* Toru Nagashima ([@mysticatea](https://github.com/mysticatea)) - committer
* Burak Yiğit Kaya ([@byk](https://github.com/byk)) - committer
* Alberto Rodríguez ([@alberto](https://github.com/alberto)) - committer
## Releases
We have scheduled releases every two weeks on Friday or Saturday.
## Frequently Asked Questions
### Why don't you like JSHint???
I do like JSHint. And I like Anton and Rick. Neither of those were deciding factors in creating this tool. The fact is that I've had a dire need for a JavaScript tool with pluggable linting rules. I had hoped JSHint would be able to do this, however after chatting with Anton, I found that the planned plugin infrastructure wasn't going to suit my purpose.
### I'm not giving up JSHint for this!
That's not really a question, but I got it. I'm not trying to convince you that ESLint is better than JSHint. The only thing I know is that ESLint is better than JSHint for what I'm doing. In the off chance you're doing something similar, it might be better for you. Otherwise, keep using JSHint, I'm certainly not going to tell you to stop using it.
### How does ESLint performance compare to JSHint and JSCS?
ESLint is slower than JSHint, usually 2-3x slower on a single file. This is because ESLint uses Espree to construct an AST before it can evaluate your code whereas JSHint evaluates your code as it's being parsed. The speed is also based on the number of rules you enable; the more rules you enable, the slower the process.
Despite being slower, we believe that ESLint is fast enough to replace JSHint without causing significant pain.
ESLint is faster than JSCS, as ESLint uses a single-pass traversal for analysis whereas JSCS using a querying model.
If you are using both JSHint and JSCS on your files, then using just ESLint will be faster.
### Is ESLint just linting or does it also check style?
ESLint does both traditional linting (looking for problematic patterns) and style checking (enforcement of conventions). You can use it for both.
### What about ECMAScript 6 support?
ESLint has full support for ECMAScript 6. By default, this support is off. You can enable ECMAScript 6 support through [configuration](http://eslint.org/docs/user-guide/configuring).
### Does ESLint support JSX?
Yes, ESLint natively supports parsing JSX syntax (this must be enabled in [configuration](http://eslint.org/docs/user-guide/configuring).). Please note that supporting JSX syntax *is not* the same as supporting React. React applies specific semantics to JSX syntax that ESLint doesn't recognize. We recommend using [eslint-plugin-react](https://www.npmjs.com/package/eslint-plugin-react) if you are using React and want React semantics.
### What about ECMAScript 7/2016 and experimental features?
ESLint doesn't natively support experimental ECMAScript language features. You can use [babel-eslint](https://github.com/babel/babel-eslint) to use any option available in Babel.
### Where to ask for help?
Join our [Mailing List](https://groups.google.com/group/eslint) or [Chatroom](https://gitter.im/eslint/eslint)
[npm-image]: https://img.shields.io/npm/v/eslint.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/eslint
[travis-image]: https://img.shields.io/travis/eslint/eslint/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/eslint/eslint
[coveralls-image]: https://img.shields.io/coveralls/eslint/eslint/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/eslint/eslint?branch=master
[downloads-image]: https://img.shields.io/npm/dm/eslint.svg?style=flat-square
[downloads-url]: https://www.npmjs.com/package/eslint

69
node_modules/eslint/bin/eslint.js generated vendored Executable file
View File

@@ -0,0 +1,69 @@
#!/usr/bin/env node
/**
* @fileoverview Main CLI that is run via the eslint command.
* @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
var exitCode = 0,
useStdIn = (process.argv.indexOf("--stdin") > -1),
init = (process.argv.indexOf("--init") > -1),
debug = (process.argv.indexOf("--debug") > -1);
// must do this initialization *before* other requires in order to work
if (debug) {
require("debug").enable("eslint:*");
}
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
// now we can safely include the other modules that use debug
var concat = require("concat-stream"),
cli = require("../lib/cli");
//------------------------------------------------------------------------------
// Execution
//------------------------------------------------------------------------------
if (useStdIn) {
process.stdin.pipe(concat({ encoding: "string" }, function(text) {
try {
exitCode = cli.execute(process.argv, text);
} catch (ex) {
console.error(ex.message);
console.error(ex.stack);
exitCode = 1;
}
}));
} else if (init) {
var configInit = require("../lib/config/config-initializer");
configInit.initializeConfig(function(err) {
if (err) {
exitCode = 1;
console.error(err.message);
console.error(err.stack);
} else {
exitCode = 0;
}
});
} else {
exitCode = cli.execute(process.argv);
}
/*
* Wait for the stdout buffer to drain.
* See https://github.com/eslint/eslint/issues/317
*/
process.on("exit", function() {
process.exit(exitCode);
});

21
node_modules/eslint/conf/blank-script.json generated vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"type": "Program",
"body": [],
"sourceType": "script",
"range": [
0,
0
],
"loc": {
"start": {
"line": 0,
"column": 0
},
"end": {
"line": 0,
"column": 0
}
},
"comments": [],
"tokens": []
}

114
node_modules/eslint/conf/environments.js generated vendored Normal file
View File

@@ -0,0 +1,114 @@
/**
* @fileoverview Defines environment settings and globals.
* @author Elan Shanker
* @copyright 2014 Elan Shanker. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var globals = require("globals");
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
builtin: globals.builtin,
browser: {
globals: globals.browser
},
node: {
globals: globals.node,
ecmaFeatures: {
globalReturn: true
}
},
commonjs: {
globals: globals.commonjs,
ecmaFeatures: {
globalReturn: true
}
},
worker: {
globals: globals.worker
},
amd: {
globals: globals.amd
},
mocha: {
globals: globals.mocha
},
jasmine: {
globals: globals.jasmine
},
jest: {
globals: globals.jest
},
phantomjs: {
globals: globals.phantomjs
},
jquery: {
globals: globals.jquery
},
qunit: {
globals: globals.qunit
},
prototypejs: {
globals: globals.prototypejs
},
shelljs: {
globals: globals.shelljs
},
meteor: {
globals: globals.meteor
},
mongo: {
globals: globals.mongo
},
protractor: {
globals: globals.protractor
},
applescript: {
globals: globals.applescript
},
nashorn: {
globals: globals.nashorn
},
serviceworker: {
globals: globals.serviceworker
},
embertest: {
globals: globals.embertest
},
webextensions: {
globals: globals.webextensions
},
es6: {
ecmaFeatures: {
arrowFunctions: true,
blockBindings: true,
regexUFlag: true,
regexYFlag: true,
templateStrings: true,
binaryLiterals: true,
octalLiterals: true,
unicodeCodePointEscapes: true,
superInFunctions: true,
defaultParams: true,
restParams: true,
forOf: true,
objectLiteralComputedProperties: true,
objectLiteralShorthandMethods: true,
objectLiteralShorthandProperties: true,
objectLiteralDuplicateProperties: true,
generators: true,
destructuring: true,
classes: true,
spread: true,
newTarget: true
}
}
};

196
node_modules/eslint/conf/eslint.json generated vendored Normal file
View File

@@ -0,0 +1,196 @@
{
"parser": "espree",
"ecmaFeatures": {},
"rules": {
"no-alert": 0,
"no-array-constructor": 0,
"no-arrow-condition": 0,
"no-bitwise": 0,
"no-caller": 0,
"no-case-declarations": 0,
"no-catch-shadow": 0,
"no-class-assign": 0,
"no-cond-assign": 2,
"no-console": 2,
"no-const-assign": 0,
"no-constant-condition": 2,
"no-continue": 0,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-div-regex": 0,
"no-dupe-class-members": 0,
"no-dupe-keys": 2,
"no-dupe-args": 2,
"no-duplicate-case": 2,
"no-else-return": 0,
"no-empty": 2,
"no-empty-character-class": 2,
"no-empty-label": 0,
"no-empty-pattern": 0,
"no-eq-null": 0,
"no-eval": 0,
"no-ex-assign": 2,
"no-extend-native": 0,
"no-extra-bind": 0,
"no-extra-boolean-cast": 2,
"no-extra-parens": 0,
"no-extra-semi": 2,
"no-fallthrough": 2,
"no-floating-decimal": 0,
"no-func-assign": 2,
"no-implicit-coercion": 0,
"no-implied-eval": 0,
"no-inline-comments": 0,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-invalid-this": 0,
"no-irregular-whitespace": 2,
"no-iterator": 0,
"no-label-var": 0,
"no-labels": 0,
"no-lone-blocks": 0,
"no-lonely-if": 0,
"no-loop-func": 0,
"no-mixed-requires": [0, false],
"no-mixed-spaces-and-tabs": [2, false],
"linebreak-style": [0, "unix"],
"no-multi-spaces": 0,
"no-multi-str": 0,
"no-multiple-empty-lines": [0, {"max": 2}],
"no-native-reassign": 0,
"no-negated-condition": 0,
"no-negated-in-lhs": 2,
"no-nested-ternary": 0,
"no-new": 0,
"no-new-func": 0,
"no-new-object": 0,
"no-new-require": 0,
"no-new-wrappers": 0,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 0,
"no-param-reassign": 0,
"no-path-concat": 0,
"no-plusplus": 0,
"no-process-env": 0,
"no-process-exit": 0,
"no-proto": 0,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-restricted-modules": 0,
"no-restricted-syntax": 0,
"no-return-assign": 0,
"no-script-url": 0,
"no-self-compare": 0,
"no-sequences": 0,
"no-shadow": 0,
"no-shadow-restricted-names": 0,
"no-spaced-func": 0,
"no-sparse-arrays": 2,
"no-sync": 0,
"no-ternary": 0,
"no-trailing-spaces": 0,
"no-this-before-super": 0,
"no-throw-literal": 0,
"no-undef": 2,
"no-undef-init": 0,
"no-undefined": 0,
"no-unexpected-multiline": 0,
"no-underscore-dangle": 0,
"no-unneeded-ternary": 0,
"no-unreachable": 2,
"no-unused-expressions": 0,
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
"no-use-before-define": 0,
"no-useless-call": 0,
"no-useless-concat": 0,
"no-void": 0,
"no-var": 0,
"no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
"no-with": 0,
"no-magic-numbers": 0,
"array-bracket-spacing": [0, "never"],
"arrow-body-style": [0, "as-needed"],
"arrow-parens": 0,
"arrow-spacing": 0,
"accessor-pairs": 0,
"block-scoped-var": 0,
"block-spacing": 0,
"brace-style": [0, "1tbs"],
"callback-return": 0,
"camelcase": 0,
"comma-dangle": [2, "never"],
"comma-spacing": 0,
"comma-style": 0,
"complexity": [0, 11],
"computed-property-spacing": [0, "never"],
"consistent-return": 0,
"consistent-this": [0, "that"],
"constructor-super": 0,
"curly": [0, "all"],
"default-case": 0,
"dot-location": 0,
"dot-notation": [0, { "allowKeywords": true }],
"eol-last": 0,
"eqeqeq": 0,
"func-names": 0,
"func-style": [0, "declaration"],
"generator-star-spacing": 0,
"global-require": 0,
"guard-for-in": 0,
"handle-callback-err": 0,
"id-length": 0,
"indent": 0,
"init-declarations": 0,
"jsx-quotes": [0, "prefer-double"],
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],
"lines-around-comment": 0,
"max-depth": [0, 4],
"max-len": [0, 80, 4],
"max-nested-callbacks": [0, 2],
"max-params": [0, 3],
"max-statements": [0, 10],
"new-cap": 0,
"new-parens": 0,
"newline-after-var": 0,
"object-curly-spacing": [0, "never"],
"object-shorthand": 0,
"one-var": [0, "always"],
"operator-assignment": [0, "always"],
"operator-linebreak": 0,
"padded-blocks": 0,
"prefer-arrow-callback": 0,
"prefer-const": 0,
"prefer-spread": 0,
"prefer-reflect": 0,
"prefer-template": 0,
"quote-props": 0,
"quotes": [0, "double"],
"radix": 0,
"id-match": 0,
"require-jsdoc": 0,
"require-yield": 0,
"semi": 0,
"semi-spacing": [0, {"before": false, "after": true}],
"sort-vars": 0,
"space-after-keywords": [0, "always"],
"space-before-keywords": [0, "always"],
"space-before-blocks": [0, "always"],
"space-before-function-paren": [0, "always"],
"space-in-parens": [0, "never"],
"space-infix-ops": 0,
"space-return-throw-case": 0,
"space-unary-ops": [0, { "words": true, "nonwords": false }],
"spaced-comment": 0,
"strict": 0,
"use-isnan": 2,
"valid-jsdoc": 0,
"valid-typeof": 2,
"vars-on-top": 0,
"wrap-iife": 0,
"wrap-regex": 0,
"yoda": [0, "never"]
}
}

150
node_modules/eslint/conf/json-schema-schema.json generated vendored Normal file
View File

@@ -0,0 +1,150 @@
{
"id": "http://json-schema.org/draft-04/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": { "$ref": "#" }
},
"positiveInteger": {
"type": "integer",
"minimum": 0
},
"positiveIntegerDefault0": {
"allOf": [ { "$ref": "#/definitions/positiveInteger" }, { "default": 0 } ]
},
"simpleTypes": {
"enum": [ "array", "boolean", "integer", "null", "number", "object", "string" ]
},
"stringArray": {
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}
},
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uri"
},
"$schema": {
"type": "string",
"format": "uri"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"minimum": 0,
"exclusiveMinimum": true
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "boolean",
"default": false
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "boolean",
"default": false
},
"maxLength": { "$ref": "#/definitions/positiveInteger" },
"minLength": { "$ref": "#/definitions/positiveIntegerDefault0" },
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"items": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/schemaArray" }
],
"default": {}
},
"maxItems": { "$ref": "#/definitions/positiveInteger" },
"minItems": { "$ref": "#/definitions/positiveIntegerDefault0" },
"uniqueItems": {
"type": "boolean",
"default": false
},
"maxProperties": { "$ref": "#/definitions/positiveInteger" },
"minProperties": { "$ref": "#/definitions/positiveIntegerDefault0" },
"required": { "$ref": "#/definitions/stringArray" },
"additionalProperties": {
"anyOf": [
{ "type": "boolean" },
{ "$ref": "#" }
],
"default": {}
},
"definitions": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": { "$ref": "#" },
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{ "$ref": "#" },
{ "$ref": "#/definitions/stringArray" }
]
}
},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{ "$ref": "#/definitions/simpleTypes" },
{
"type": "array",
"items": { "$ref": "#/definitions/simpleTypes" },
"minItems": 1,
"uniqueItems": true
}
]
},
"allOf": { "$ref": "#/definitions/schemaArray" },
"anyOf": { "$ref": "#/definitions/schemaArray" },
"oneOf": { "$ref": "#/definitions/schemaArray" },
"not": { "$ref": "#" }
},
"dependencies": {
"exclusiveMaximum": [ "maximum" ],
"exclusiveMinimum": [ "minimum" ]
},
"default": {}
}

17
node_modules/eslint/conf/replacements.json generated vendored Normal file
View File

@@ -0,0 +1,17 @@
{
"rules": {
"generator-star": ["generator-star-spacing"],
"global-strict": ["strict"],
"no-comma-dangle": ["comma-dangle"],
"no-empty-class": ["no-empty-character-class"],
"no-extra-strict": ["strict"],
"no-reserved-keys": ["quote-props"],
"no-space-before-semi": ["semi-spacing"],
"no-wrap-func": ["no-extra-parens"],
"space-after-function-name": ["space-before-function-paren"],
"space-before-function-parentheses": ["space-before-function-paren"],
"space-in-brackets": ["object-curly-spacing", "array-bracket-spacing", "computed-property-spacing"],
"space-unary-word-ops": ["space-unary-ops"],
"spaced-line-comment": ["spaced-comment"]
}
}

13
node_modules/eslint/lib/api.js generated vendored Normal file
View File

@@ -0,0 +1,13 @@
/**
* @fileoverview Expose out ESLint and CLI to require.
* @author Ian Christian Myers
*/
"use strict";
module.exports = {
linter: require("./eslint"),
CLIEngine: require("./cli-engine"),
RuleTester: require("./testers/rule-tester"),
SourceCode: require("./util/source-code")
};

154
node_modules/eslint/lib/ast-utils.js generated vendored Normal file
View File

@@ -0,0 +1,154 @@
/**
* @fileoverview Common utils for AST.
* @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var esutils = require("esutils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks reference if is non initializer and writable.
* @param {Reference} reference - A reference to check.
* @param {int} index - The index of the reference in the references.
* @param {Reference[]} references - The array that the reference belongs to.
* @returns {boolean} Success/Failure
* @private
*/
function isModifyingReference(reference, index, references) {
var identifier = reference.identifier;
return (identifier &&
reference.init === false &&
reference.isWrite() &&
// Destructuring assignments can have multiple default value,
// so possibly there are multiple writeable references for the same identifier.
(index === 0 || references[index - 1].identifier !== identifier)
);
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
/**
* Determines whether two adjacent tokens are on the same line.
* @param {Object} left - The left token object.
* @param {Object} right - The right token object.
* @returns {boolean} Whether or not the tokens are on the same line.
* @public
*/
isTokenOnSameLine: function(left, right) {
return left.loc.end.line === right.loc.start.line;
},
/**
* Checks whether or not a node is `null` or `undefined`.
* @param {ASTNode} node - A node to check.
* @returns {boolean} Whether or not the node is a `null` or `undefined`.
* @public
*/
isNullOrUndefined: function(node) {
return (
(node.type === "Literal" && node.value === null) ||
(node.type === "Identifier" && node.name === "undefined") ||
(node.type === "UnaryExpression" && node.operator === "void")
);
},
/**
* Checks whether or not a given node is a string literal.
* @param {ASTNode} node - A node to check.
* @returns {boolean} `true` if the node is a string literal.
*/
isStringLiteral: function(node) {
return (
(node.type === "Literal" && typeof node.value === "string") ||
node.type === "TemplateLiteral"
);
},
/**
* Gets references which are non initializer and writable.
* @param {Reference[]} references - An array of references.
* @returns {Reference[]} An array of only references which are non initializer and writable.
* @public
*/
getModifyingReferences: function(references) {
return references.filter(isModifyingReference);
},
/**
* Validate that a string passed in is surrounded by the specified character
* @param {string} val The text to check.
* @param {string} character The character to see if it's surrounded by.
* @returns {boolean} True if the text is surrounded by the character, false if not.
* @private
*/
isSurroundedBy: function(val, character) {
return val[0] === character && val[val.length - 1] === character;
},
/**
* Returns whether the provided node is an ESLint directive comment or not
* @param {LineComment|BlockComment} node The node to be checked
* @returns {boolean} `true` if the node is an ESLint directive comment
*/
isDirectiveComment: function(node) {
var comment = node.value.trim();
return (
node.type === "Line" && comment.indexOf("eslint-") === 0 ||
node.type === "Block" && (
comment.indexOf("global ") === 0 ||
comment.indexOf("eslint ") === 0 ||
comment.indexOf("eslint-") === 0
)
);
},
/**
* Gets the trailing statement of a given node.
*
* if (code)
* consequent;
*
* When taking this `IfStatement`, returns `consequent;` statement.
*
* @param {ASTNode} A node to get.
* @returns {ASTNode|null} The trailing statement's node.
*/
getTrailingStatement: esutils.ast.trailingStatement,
/**
* Finds the variable by a given name in a given scope and its upper scopes.
*
* @param {escope.Scope} initScope - A scope to start find.
* @param {string} name - A variable name to find.
* @returns {escope.Variable|null} A found variable or `null`.
*/
getVariableByName: function(initScope, name) {
var scope = initScope;
while (scope) {
var variable = scope.set.get(name);
if (variable) {
return variable;
}
scope = scope.upper;
}
return null;
}
};

730
node_modules/eslint/lib/cli-engine.js generated vendored Normal file
View File

@@ -0,0 +1,730 @@
/**
* @fileoverview Main CLI object.
* @author Nicholas C. Zakas
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* See LICENSE in root directory for full license.
*/
"use strict";
/*
* The CLI object should *not* call process.exit() directly. It should only return
* exit codes. This allows other programs to use the CLI object and still control
* when the program exits.
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var fs = require("fs"),
path = require("path"),
assign = require("object-assign"),
debug = require("debug"),
shell = require("shelljs"),
rules = require("./rules"),
eslint = require("./eslint"),
IgnoredPaths = require("./ignored-paths"),
Config = require("./config"),
util = require("./util"),
fileEntryCache = require("file-entry-cache"),
globUtil = require("./util/glob-util"),
SourceCodeFixer = require("./util/source-code-fixer"),
validator = require("./config/config-validator"),
stringify = require("json-stable-stringify"),
crypto = require( "crypto" ),
pkg = require("../package.json");
var DEFAULT_PARSER = require("../conf/eslint.json").parser;
//------------------------------------------------------------------------------
// Typedefs
//------------------------------------------------------------------------------
/**
* The options to configure a CLI engine with.
* @typedef {Object} CLIEngineOptions
* @property {string} configFile The configuration file to use.
* @property {boolean|object} baseConfig Base config object. True enables recommend rules and environments.
* @property {boolean} ignore False disables use of .eslintignore.
* @property {string[]} rulePaths An array of directories to load custom rules from.
* @property {boolean} useEslintrc False disables looking for .eslintrc
* @property {string[]} envs An array of environments to load.
* @property {string[]} globals An array of global variables to declare.
* @property {string[]} extensions An array of file extensions to check.
* @property {Object<string,*>} rules An object of rules to use.
* @property {string} ignorePath The ignore file to use instead of .eslintignore.
*/
/**
* A linting warning or error.
* @typedef {Object} LintMessage
* @property {string} message The message to display to the user.
*/
/**
* A linting result.
* @typedef {Object} LintResult
* @property {string} filePath The path to the file that was linted.
* @property {LintMessage[]} messages All of the messages for the result.
*/
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
var defaultOptions = {
configFile: null,
baseConfig: false,
rulePaths: [],
useEslintrc: true,
envs: [],
globals: [],
rules: {},
extensions: [".js"],
ignore: true,
ignorePath: null,
parser: DEFAULT_PARSER,
cache: false,
// in order to honor the cacheFile option if specified
// this option should not have a default value otherwise
// it will always be used
cacheLocation: "",
cacheFile: ".eslintcache",
fix: false,
allowInlineConfig: true
},
loadedPlugins = Object.create(null);
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
debug = debug("eslint:cli-engine");
/**
* Load the given plugins if they are not loaded already.
* @param {string[]} pluginNames An array of plugin names which should be loaded.
* @returns {void}
*/
function loadPlugins(pluginNames) {
if (pluginNames) {
pluginNames.forEach(function(pluginName) {
var pluginNamespace = util.getNamespace(pluginName),
pluginNameWithoutNamespace = util.removeNameSpace(pluginName),
pluginNameWithoutPrefix = util.removePluginPrefix(pluginNameWithoutNamespace),
plugin;
if (!loadedPlugins[pluginNameWithoutPrefix]) {
debug("Load plugin " + pluginNameWithoutPrefix);
plugin = require(pluginNamespace + util.PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix);
// if this plugin has rules, import them
if (plugin.rules) {
rules.import(plugin.rules, pluginNameWithoutPrefix);
}
loadedPlugins[pluginNameWithoutPrefix] = plugin;
}
});
}
}
/**
* It will calculate the error and warning count for collection of messages per file
* @param {Object[]} messages - Collection of messages
* @returns {Object} Contains the stats
* @private
*/
function calculateStatsPerFile(messages) {
return messages.reduce(function(stat, message) {
if (message.fatal || message.severity === 2) {
stat.errorCount++;
} else {
stat.warningCount++;
}
return stat;
}, {
errorCount: 0,
warningCount: 0
});
}
/**
* It will calculate the error and warning count for collection of results from all files
* @param {Object[]} results - Collection of messages from all the files
* @returns {Object} Contains the stats
* @private
*/
function calculateStatsPerRun(results) {
return results.reduce(function(stat, result) {
stat.errorCount += result.errorCount;
stat.warningCount += result.warningCount;
return stat;
}, {
errorCount: 0,
warningCount: 0
});
}
/**
* Processes an source code using ESLint.
* @param {string} text The source code to check.
* @param {Object} configHelper The configuration options for ESLint.
* @param {string} filename An optional string representing the texts filename.
* @param {boolean} fix Indicates if fixes should be processed.
* @param {boolean} allowInlineConfig Allow/ignore comments that change config.
* @returns {Result} The results for linting on this text.
* @private
*/
function processText(text, configHelper, filename, fix, allowInlineConfig) {
// clear all existing settings for a new file
eslint.reset();
var filePath,
config,
messages,
stats,
fileExtension = path.extname(filename),
processor,
fixedResult;
if (filename) {
filePath = path.resolve(filename);
}
filename = filename || "<text>";
debug("Linting " + filename);
config = configHelper.getConfig(filePath);
loadPlugins(config.plugins);
for (var plugin in loadedPlugins) {
if (loadedPlugins[plugin].processors && Object.keys(loadedPlugins[plugin].processors).indexOf(fileExtension) >= 0) {
processor = loadedPlugins[plugin].processors[fileExtension];
break;
}
}
if (processor) {
debug("Using processor");
var parsedBlocks = processor.preprocess(text, filename);
var unprocessedMessages = [];
parsedBlocks.forEach(function(block) {
unprocessedMessages.push(eslint.verify(block, config, {
filename: filename,
allowInlineConfig: allowInlineConfig
}));
});
// TODO(nzakas): Figure out how fixes might work for processors
messages = processor.postprocess(unprocessedMessages, filename);
} else {
messages = eslint.verify(text, config, {
filename: filename,
allowInlineConfig: allowInlineConfig
});
if (fix) {
debug("Generating fixed text for " + filename);
fixedResult = SourceCodeFixer.applyFixes(eslint.getSourceCode(), messages);
messages = fixedResult.messages;
}
}
stats = calculateStatsPerFile(messages);
var result = {
filePath: filename,
messages: messages,
errorCount: stats.errorCount,
warningCount: stats.warningCount
};
if (fixedResult && fixedResult.fixed) {
result.output = fixedResult.output;
}
return result;
}
/**
* Processes an individual file using ESLint. Files used here are known to
* exist, so no need to check that here.
* @param {string} filename The filename of the file being checked.
* @param {Object} configHelper The configuration options for ESLint.
* @param {Object} options The CLIEngine options object.
* @returns {Result} The results for linting on this file.
* @private
*/
function processFile(filename, configHelper, options) {
var text = fs.readFileSync(path.resolve(filename), "utf8"),
result = processText(text, configHelper, filename, options.fix, options.allowInlineConfig);
return result;
}
/**
* Returns result with warning by ignore settings
* @param {string} filePath File path of checked code
* @returns {Result} Result with single warning
* @private
*/
function createIgnoreResult(filePath) {
return {
filePath: path.resolve(filePath),
messages: [
{
fatal: false,
severity: 1,
message: "File ignored because of your .eslintignore file. Use --no-ignore to override."
}
],
errorCount: 0,
warningCount: 1
};
}
/**
* Checks if the given message is an error message.
* @param {object} message The message to check.
* @returns {boolean} Whether or not the message is an error message.
* @private
*/
function isErrorMessage(message) {
return message.severity === 2;
}
/**
* create a md5Hash of a given string
* @param {string} str the string to calculate the hash for
* @returns {string} the calculated hash
*/
function md5Hash(str) {
return crypto
.createHash("md5")
.update(str, "utf8")
.digest("hex");
}
/**
* return the cacheFile to be used by eslint, based on whether the provided parameter is
* a directory or looks like a directory (ends in `path.sep`), in which case the file
* name will be the `cacheFile/.cache_hashOfCWD`
*
* if cacheFile points to a file or looks like a file then in will just use that file
*
* @param {string} cacheFile The name of file to be used to store the cache
* @returns {string} the resolved path to the cache file
*/
function getCacheFile(cacheFile) {
// make sure the path separators are normalized for the environment/os
// keeping the trailing path separator if present
cacheFile = path.normalize(cacheFile);
var resolvedCacheFile = path.resolve(cacheFile);
var looksLikeADirectory = cacheFile[cacheFile.length - 1 ] === path.sep;
/**
* return the name for the cache file in case the provided parameter is a directory
* @returns {string} the resolved path to the cacheFile
*/
function getCacheFileForDirectory() {
return path.join(resolvedCacheFile, ".cache_" + md5Hash(process.cwd()));
}
var fileStats;
try {
fileStats = fs.lstatSync(resolvedCacheFile);
} catch (ex) {
fileStats = null;
}
// in case the file exists we need to verify if the provided path
// is a directory or a file. If it is a directory we want to create a file
// inside that directory
if (fileStats) {
// is a directory or is a file, but the original file the user provided
// looks like a directory but `path.resolve` removed the `last path.sep`
// so we need to still treat this like a directory
if (fileStats.isDirectory() || looksLikeADirectory) {
return getCacheFileForDirectory();
}
// is file so just use that file
return resolvedCacheFile;
}
// here we known the file or directory doesn't exist,
// so we will try to infer if its a directory if it looks like a directory
// for the current operating system.
// if the last character passed is a path separator we assume is a directory
if (looksLikeADirectory) {
return getCacheFileForDirectory();
}
return resolvedCacheFile;
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* Creates a new instance of the core CLI engine.
* @param {CLIEngineOptions} options The options for this instance.
* @constructor
*/
function CLIEngine(options) {
/**
* Stored options for this instance
* @type {Object}
*/
this.options = assign(Object.create(defaultOptions), options || {});
var cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile);
/**
* cache used to not operate on files that haven't changed since last successful
* execution (e.g. file passed with no errors and no warnings
* @type {Object}
*/
this._fileCache = fileEntryCache.create(cacheFile); // eslint-disable-line no-underscore-dangle
if (!this.options.cache) {
this._fileCache.destroy(); // eslint-disable-line no-underscore-dangle
}
// load in additional rules
if (this.options.rulePaths) {
this.options.rulePaths.forEach(function(rulesdir) {
debug("Loading rules from " + rulesdir);
rules.load(rulesdir);
});
}
Object.keys(this.options.rules || {}).forEach(function(name) {
validator.validateRuleOptions(name, this.options.rules[name], "CLI");
}.bind(this));
}
/**
* Returns the formatter representing the given format or null if no formatter
* with the given name can be found.
* @param {string} [format] The name of the format to load or the path to a
* custom formatter.
* @returns {Function} The formatter function or null if not found.
*/
CLIEngine.getFormatter = function(format) {
var formatterPath;
// default is stylish
format = format || "stylish";
// only strings are valid formatters
if (typeof format === "string") {
// replace \ with / for Windows compatibility
format = format.replace(/\\/g, "/");
// if there's a slash, then it's a file
if (format.indexOf("/") > -1) {
formatterPath = path.resolve(process.cwd(), format);
} else {
formatterPath = "./formatters/" + format;
}
try {
return require(formatterPath);
} catch (ex) {
return null;
}
} else {
return null;
}
};
/**
* Returns results that only contains errors.
* @param {LintResult[]} results The results to filter.
* @returns {LintResult[]} The filtered results.
*/
CLIEngine.getErrorResults = function(results) {
var filtered = [];
results.forEach(function(result) {
var filteredMessages = result.messages.filter(isErrorMessage);
if (filteredMessages.length > 0) {
filtered.push({
filePath: result.filePath,
messages: filteredMessages
});
}
});
return filtered;
};
/**
* Outputs fixes from the given results to files.
* @param {Object} report The report object created by CLIEngine.
* @returns {void}
*/
CLIEngine.outputFixes = function(report) {
report.results.filter(function(result) {
return result.hasOwnProperty("output");
}).forEach(function(result) {
fs.writeFileSync(result.filePath, result.output);
});
};
CLIEngine.prototype = {
constructor: CLIEngine,
/**
* Add a plugin by passing it's configuration
* @param {string} name Name of the plugin.
* @param {Object} pluginobject Plugin configuration object.
* @returns {void}
*/
addPlugin: function(name, pluginobject) {
var pluginNameWithoutPrefix = util.removePluginPrefix(util.removeNameSpace(name));
if (pluginobject.rules) {
rules.import(pluginobject.rules, pluginNameWithoutPrefix);
}
loadedPlugins[pluginNameWithoutPrefix] = pluginobject;
},
/**
* Resolves the patterns passed into executeOnFiles() into glob-based patterns
* for easier handling.
* @param {string[]} patterns The file patterns passed on the command line.
* @returns {string[]} The equivalent glob patterns.
*/
resolveFileGlobPatterns: function(patterns) {
return globUtil.resolveFileGlobPatterns(patterns, this.options.extensions);
},
/**
* Executes the current configuration on an array of file and directory names.
* @param {string[]} patterns An array of file and directory names.
* @returns {Object} The results for all files that were linted.
*/
executeOnFiles: function(patterns) {
var results = [],
processed = {},
options = this.options,
fileCache = this._fileCache, // eslint-disable-line no-underscore-dangle
configHelper = new Config(options),
stats,
startTime,
prevConfig; // the previous configuration used
startTime = Date.now();
patterns = this.resolveFileGlobPatterns(patterns);
/**
* Calculates the hash of the config file used to validate a given file
* @param {string} filename The path of the file to retrieve a config object for to calculate the hash
* @returns {string} the hash of the config
*/
function hashOfConfigFor(filename) {
var config = configHelper.getConfig(filename);
if (!prevConfig) {
prevConfig = {};
}
// reuse the previously hashed config if the config hasn't changed
if (prevConfig.config !== config) {
// config changed so we need to calculate the hash of the config
// and the hash of the plugins being used
prevConfig.config = config;
var eslintVersion = pkg.version;
prevConfig.hash = md5Hash(eslintVersion + "_" + stringify(config));
}
return prevConfig.hash;
}
/**
* Executes the linter on a file defined by the `filename`. Skips
* unsupported file extensions and any files that are already linted.
* @param {string} filename The resolved filename of the file to be linted
* @returns {void}
*/
function executeOnFile(filename) {
var hashOfConfig;
if (processed[filename]) {
return;
}
if (options.cache) {
// get the descriptor for this file
// with the metadata and the flag that determines if
// the file has changed
var descriptor = fileCache.getFileDescriptor(filename);
var meta = descriptor.meta || {};
hashOfConfig = hashOfConfigFor(filename);
var changed = descriptor.changed || meta.hashOfConfig !== hashOfConfig;
if (!changed) {
debug("Skipping file since hasn't changed: " + filename);
// Adding the filename to the processed hashmap
// so the reporting is not affected (showing a warning about .eslintignore being used
// when it is not really used)
processed[filename] = true;
// Add the the cached results (always will be 0 error and 0 warnings)
// cause we don't save to cache files that failed
// to guarantee that next execution will process those files as well
results.push(descriptor.meta.results);
// move to the next file
return;
}
}
debug("Processing " + filename);
processed[filename] = true;
var res = processFile(filename, configHelper, options);
if (options.cache) {
// if a file contains errors or warnings we don't want to
// store the file in the cache so we can guarantee that
// next execution will also operate on this file
if ( res.errorCount > 0 || res.warningCount > 0 ) {
debug("File has problems, skipping it: " + filename);
// remove the entry from the cache
fileCache.removeEntry( filename );
} else {
// since the file passed we store the result here
// TODO: check this as we might not need to store the
// successful runs as it will always should be 0 error 0 warnings
descriptor.meta.hashOfConfig = hashOfConfig;
descriptor.meta.results = res;
}
}
results.push(res);
}
// Lint each desired file
globUtil.listFilesToProcess(patterns, options).forEach(executeOnFile);
// only warn for files explicitly passed on the command line
if (options.ignore) {
patterns.forEach(function(file) {
var fullPath = path.resolve(file);
if (shell.test("-f", fullPath) && !processed[fullPath]) {
results.push(createIgnoreResult(file));
}
});
}
stats = calculateStatsPerRun(results);
if (options.cache) {
// persist the cache to disk
fileCache.reconcile();
}
debug("Linting complete in: " + (Date.now() - startTime) + "ms");
return {
results: results,
errorCount: stats.errorCount,
warningCount: stats.warningCount
};
},
/**
* Executes the current configuration on text.
* @param {string} text A string of JavaScript code to lint.
* @param {string} filename An optional string representing the texts filename.
* @returns {Object} The results for the linting.
*/
executeOnText: function(text, filename) {
var results = [],
stats,
options = this.options,
configHelper = new Config(options),
ignoredPaths = IgnoredPaths.load(options),
exclude = ignoredPaths.contains.bind(ignoredPaths);
if (filename && options.ignore && exclude(filename)) {
results.push(createIgnoreResult(filename));
} else {
results.push(processText(text, configHelper, filename, options.fix, options.allowInlineConfig));
}
stats = calculateStatsPerRun(results);
return {
results: results,
errorCount: stats.errorCount,
warningCount: stats.warningCount
};
},
/**
* Returns a configuration object for the given file based on the CLI options.
* This is the same logic used by the ESLint CLI executable to determine
* configuration for each file it processes.
* @param {string} filePath The path of the file to retrieve a config object for.
* @returns {Object} A configuration object for the file.
*/
getConfigForFile: function(filePath) {
var configHelper = new Config(this.options);
return configHelper.getConfig(filePath);
},
/**
* Checks if a given path is ignored by ESLint.
* @param {string} filePath The path of the file to check.
* @returns {boolean} Whether or not the given path is ignored.
*/
isPathIgnored: function(filePath) {
var ignoredPaths;
if (this.options.ignore) {
ignoredPaths = IgnoredPaths.load(this.options);
return ignoredPaths.contains(filePath);
}
return false;
},
getFormatter: CLIEngine.getFormatter
};
module.exports = CLIEngine;

191
node_modules/eslint/lib/cli.js generated vendored Normal file
View File

@@ -0,0 +1,191 @@
/**
* @fileoverview Main CLI object.
* @author Nicholas C. Zakas
*/
"use strict";
/*
* The CLI object should *not* call process.exit() directly. It should only return
* exit codes. This allows other programs to use the CLI object and still control
* when the program exits.
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var fs = require("fs"),
path = require("path"),
debug = require("debug"),
options = require("./options"),
CLIEngine = require("./cli-engine"),
mkdirp = require("mkdirp"),
log = require("./logging");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
debug = debug("eslint:cli");
/**
* Translates the CLI options into the options expected by the CLIEngine.
* @param {Object} cliOptions The CLI options to translate.
* @returns {CLIEngineOptions} The options object for the CLIEngine.
* @private
*/
function translateOptions(cliOptions) {
return {
envs: cliOptions.env,
extensions: cliOptions.ext,
rules: cliOptions.rule,
plugins: cliOptions.plugin,
globals: cliOptions.global,
ignore: cliOptions.ignore,
ignorePath: cliOptions.ignorePath,
ignorePattern: cliOptions.ignorePattern,
configFile: cliOptions.config,
rulePaths: cliOptions.rulesdir,
useEslintrc: cliOptions.eslintrc,
parser: cliOptions.parser,
cache: cliOptions.cache,
cacheFile: cliOptions.cacheFile,
cacheLocation: cliOptions.cacheLocation,
fix: cliOptions.fix,
allowInlineConfig: cliOptions.inlineConfig
};
}
/**
* Outputs the results of the linting.
* @param {CLIEngine} engine The CLIEngine to use.
* @param {LintResult[]} results The results to print.
* @param {string} format The name of the formatter to use or the path to the formatter.
* @param {string} outputFile The path for the output file.
* @returns {boolean} True if the printing succeeds, false if not.
* @private
*/
function printResults(engine, results, format, outputFile) {
var formatter,
output,
filePath;
formatter = engine.getFormatter(format);
if (!formatter) {
log.error("Could not find formatter '%s'.", format);
return false;
}
output = formatter(results);
if (output) {
if (outputFile) {
filePath = path.resolve(process.cwd(), outputFile);
if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
log.error("Cannot write to output file path, it is a directory: %s", outputFile);
return false;
}
try {
mkdirp.sync(path.dirname(filePath));
fs.writeFileSync(filePath, output);
} catch (ex) {
log.error("There was a problem writing the output file:\n%s", ex);
return false;
}
} else {
log.info(output);
}
}
return true;
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* Encapsulates all CLI behavior for eslint. Makes it easier to test as well as
* for other Node.js programs to effectively run the CLI.
*/
var cli = {
/**
* Executes the CLI based on an array of arguments that is passed in.
* @param {string|Array|Object} args The arguments to process.
* @param {string} [text] The text to lint (used for TTY).
* @returns {int} The exit code for the operation.
*/
execute: function(args, text) {
var currentOptions,
files,
report,
engine,
tooManyWarnings;
try {
currentOptions = options.parse(args);
} catch (error) {
log.error(error.message);
return 1;
}
files = currentOptions._;
if (currentOptions.version) { // version from package.json
log.info("v" + require("../package.json").version);
} else if (currentOptions.help || (!files.length && !text)) {
log.info(options.generateHelp());
} else {
debug("Running on " + (text ? "text" : "files"));
// disable --fix for piped-in code until we know how to do it correctly
if (text && currentOptions.fix) {
log.error("The --fix option is not available for piped-in code.");
return 1;
}
engine = new CLIEngine(translateOptions(currentOptions));
report = text ? engine.executeOnText(text, currentOptions.stdinFilename) : engine.executeOnFiles(files);
if (currentOptions.fix) {
debug("Fix mode enabled - applying fixes");
CLIEngine.outputFixes(report);
}
if (currentOptions.quiet) {
debug("Quiet mode enabled - filtering out warnings");
report.results = CLIEngine.getErrorResults(report.results);
}
if (printResults(engine, report.results, currentOptions.format, currentOptions.outputFile)) {
tooManyWarnings = currentOptions.maxWarnings >= 0 && report.warningCount > currentOptions.maxWarnings;
if (!report.errorCount && tooManyWarnings) {
log.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings);
}
return (report.errorCount || tooManyWarnings) ? 1 : 0;
} else {
return 1;
}
}
return 0;
}
};
module.exports = cli;

336
node_modules/eslint/lib/config.js generated vendored Normal file
View File

@@ -0,0 +1,336 @@
/**
* @fileoverview Responsible for loading config files
* @author Seth McLaughlin
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* @copyright 2014 Michael McLaughlin. All rights reserved.
* @copyright 2013 Seth McLaughlin. All rights reserved.
* See LICENSE in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var path = require("path"),
ConfigOps = require("./config/config-ops"),
ConfigFile = require("./config/config-file"),
util = require("./util"),
FileFinder = require("./file-finder"),
debug = require("debug"),
userHome = require("user-home"),
isResolvable = require("is-resolvable"),
pathIsInside = require("path-is-inside");
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var PACKAGE_CONFIG_FILENAME = "package.json",
PERSONAL_CONFIG_DIR = userHome || null;
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
var loadedPlugins = Object.create(null);
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
debug = debug("eslint:config");
/**
* Check if item is an javascript object
* @param {*} item object to check for
* @returns {boolean} True if its an object
* @private
*/
function isObject(item) {
return typeof item === "object" && !Array.isArray(item) && item !== null;
}
/**
* Load and parse a JSON config object from a file.
* @param {string|Object} configToLoad the path to the JSON config file or the config object itself.
* @returns {Object} the parsed config object (empty object if there was a parse error)
* @private
*/
function loadConfig(configToLoad) {
var config = {},
filePath = "";
if (configToLoad) {
if (isObject(configToLoad)) {
config = configToLoad;
if (config.extends) {
config = ConfigFile.applyExtends(config, filePath);
}
} else {
filePath = configToLoad;
config = ConfigFile.load(filePath);
}
}
return config;
}
/**
* Load configuration for all plugins provided.
* @param {string[]} pluginNames An array of plugin names which should be loaded.
* @returns {Object} all plugin configurations merged together
*/
function getPluginsConfig(pluginNames) {
var pluginConfig = {};
pluginNames.forEach(function(pluginName) {
var pluginNamespace = util.getNamespace(pluginName),
pluginNameWithoutNamespace = util.removeNameSpace(pluginName),
pluginNameWithoutPrefix = util.removePluginPrefix(pluginNameWithoutNamespace),
plugin = {},
rules = {};
if (!loadedPlugins[pluginNameWithoutPrefix]) {
try {
plugin = require(pluginNamespace + util.PLUGIN_NAME_PREFIX + pluginNameWithoutPrefix);
loadedPlugins[pluginNameWithoutPrefix] = plugin;
} catch (err) {
debug("Failed to load plugin configuration for " + pluginNameWithoutPrefix + ". Proceeding without it.");
plugin = { rulesConfig: {}};
}
} else {
plugin = loadedPlugins[pluginNameWithoutPrefix];
}
if (!plugin.rulesConfig) {
plugin.rulesConfig = {};
}
Object.keys(plugin.rulesConfig).forEach(function(item) {
rules[pluginNameWithoutPrefix + "/" + item] = plugin.rulesConfig[item];
});
pluginConfig = ConfigOps.merge(pluginConfig, rules);
});
return {rules: pluginConfig};
}
/**
* Get personal config object from ~/.eslintrc.
* @returns {Object} the personal config object (empty object if there is no personal config)
* @private
*/
function getPersonalConfig() {
var config = {},
filename;
if (PERSONAL_CONFIG_DIR) {
filename = ConfigFile.getFilenameForDirectory(PERSONAL_CONFIG_DIR);
if (filename) {
debug("Using personal config");
config = loadConfig(filename);
}
}
return config;
}
/**
* Get a local config object.
* @param {Object} thisConfig A Config object.
* @param {string} directory The directory to start looking in for a local config file.
* @returns {Object} The local config object, or an empty object if there is no local config.
*/
function getLocalConfig(thisConfig, directory) {
var found,
i,
localConfig,
localConfigFile,
config = {},
localConfigFiles = thisConfig.findLocalConfigFiles(directory),
numFiles = localConfigFiles.length,
rootPath,
projectConfigPath = ConfigFile.getFilenameForDirectory(process.cwd());
for (i = 0; i < numFiles; i++) {
localConfigFile = localConfigFiles[i];
// Don't consider the personal config file in the home directory,
// except if the home directory is the same as the current working directory
if (path.dirname(localConfigFile) === PERSONAL_CONFIG_DIR && localConfigFile !== projectConfigPath) {
continue;
}
// If root flag is set, don't consider file if it is above root
if (rootPath && !pathIsInside(path.dirname(localConfigFile), rootPath)) {
continue;
}
debug("Loading " + localConfigFile);
localConfig = loadConfig(localConfigFile);
// Don't consider a local config file found if the config is null
if (!localConfig) {
continue;
}
// Check for root flag
if (localConfig.root === true) {
rootPath = path.dirname(localConfigFile);
}
found = true;
debug("Using " + localConfigFile);
config = ConfigOps.merge(localConfig, config);
}
// Use the personal config file if there are no other local config files found.
return found ? config : ConfigOps.merge(config, getPersonalConfig());
}
//------------------------------------------------------------------------------
// API
//------------------------------------------------------------------------------
/**
* Config
* @constructor
* @class Config
* @param {Object} options Options to be passed in
* @param {string} [cwd] current working directory. Defaults to process.cwd()
*/
function Config(options) {
var useConfig;
options = options || {};
this.ignore = options.ignore;
this.ignorePath = options.ignorePath;
this.cache = {};
this.parser = options.parser;
this.baseConfig = options.baseConfig ? loadConfig(options.baseConfig) : { rules: {} };
this.useEslintrc = (options.useEslintrc !== false);
this.env = (options.envs || []).reduce(function(envs, name) {
envs[name] = true;
return envs;
}, {});
this.globals = (options.globals || []).reduce(function(globals, def) {
// Default "foo" to false and handle "foo:false" and "foo:true"
var parts = def.split(":");
globals[parts[0]] = (parts.length > 1 && parts[1] === "true");
return globals;
}, {});
useConfig = options.configFile;
this.options = options;
if (useConfig) {
debug("Using command line config " + useConfig);
if (isResolvable(useConfig) || isResolvable("eslint-config-" + useConfig) || useConfig.charAt(0) === "@") {
this.useSpecificConfig = loadConfig(useConfig);
} else {
this.useSpecificConfig = loadConfig(path.resolve(process.cwd(), useConfig));
}
}
}
/**
* Build a config object merging the base config (conf/eslint.json), the
* environments config (conf/environments.js) and eventually the user config.
* @param {string} filePath a file in whose directory we start looking for a local config
* @returns {Object} config object
*/
Config.prototype.getConfig = function(filePath) {
var config,
userConfig,
directory = filePath ? path.dirname(filePath) : process.cwd(),
pluginConfig;
debug("Constructing config for " + (filePath ? filePath : "text"));
config = this.cache[directory];
if (config) {
debug("Using config from cache");
return config;
}
// Step 1: Determine user-specified config from .eslintrc and package.json files
if (this.useEslintrc) {
debug("Using .eslintrc and package.json files");
userConfig = getLocalConfig(this, directory);
} else {
debug("Not using .eslintrc or package.json files");
userConfig = {};
}
// Step 2: Create a copy of the baseConfig
config = ConfigOps.merge({parser: this.parser}, this.baseConfig);
// Step 3: Merge in the user-specified configuration from .eslintrc and package.json
config = ConfigOps.merge(config, userConfig);
// Step 4: Merge in command line config file
if (this.useSpecificConfig) {
debug("Merging command line config file");
config = ConfigOps.merge(config, this.useSpecificConfig);
}
// Step 5: Merge in command line environments
debug("Merging command line environment settings");
config = ConfigOps.merge(config, ConfigOps.createEnvironmentConfig(this.env));
// Step 6: Merge in command line rules
if (this.options.rules) {
debug("Merging command line rules");
config = ConfigOps.merge(config, { rules: this.options.rules });
}
// Step 7: Merge in command line globals
config = ConfigOps.merge(config, { globals: this.globals });
// Step 8: Merge in command line plugins
if (this.options.plugins) {
debug("Merging command line plugins");
pluginConfig = getPluginsConfig(this.options.plugins);
config = ConfigOps.merge(config, { plugins: this.options.plugins });
}
// Step 9: Merge in plugin specific rules in reverse
if (config.plugins) {
pluginConfig = getPluginsConfig(config.plugins);
config = ConfigOps.merge(pluginConfig, config);
}
this.cache[directory] = config;
return config;
};
/**
* Find local config files from directory and parent directories.
* @param {string} directory The directory to start searching from.
* @returns {string[]} The paths of local config files found.
*/
Config.prototype.findLocalConfigFiles = function(directory) {
if (!this.localConfigFinder) {
this.localConfigFinder = new FileFinder(ConfigFile.CONFIG_FILES, PACKAGE_CONFIG_FILENAME);
}
return this.localConfigFinder.findAllInDirectoryAndParents(directory);
};
module.exports = Config;

440
node_modules/eslint/lib/config/config-file.js generated vendored Normal file
View File

@@ -0,0 +1,440 @@
/**
* @fileoverview Helper to locate and load configuration files.
* @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
/* eslint no-use-before-define: 0 */
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var debug = require("debug"),
fs = require("fs"),
path = require("path"),
ConfigOps = require("./config-ops"),
validator = require("./config-validator"),
stripComments = require("strip-json-comments"),
isAbsolutePath = require("path-is-absolute");
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
var CONFIG_FILES = [
".eslintrc.js",
".eslintrc.yaml",
".eslintrc.yml",
".eslintrc.json",
".eslintrc"
];
debug = debug("eslint:config-file");
/**
* Convenience wrapper for synchronously reading file contents.
* @param {string} filePath The filename to read.
* @returns {string} The file contents.
* @private
*/
function readFile(filePath) {
return fs.readFileSync(filePath, "utf8");
}
/**
* Determines if a given string represents a filepath or not using the same
* conventions as require(), meaning that the first character must be nonalphanumeric
* and not the @ sign which is used for scoped packages to be considered a file path.
* @param {string} filePath The string to check.
* @returns {boolean} True if it's a filepath, false if not.
* @private
*/
function isFilePath(filePath) {
return isAbsolutePath(filePath) || !/\w|@/.test(filePath.charAt(0));
}
/**
* Loads a YAML configuration from a file.
* @param {string} filePath The filename to load.
* @returns {Object} The configuration object from the file.
* @throws {Error} If the file cannot be read.
* @private
*/
function loadYAMLConfigFile(filePath) {
debug("Loading YAML config file: " + filePath);
// lazy load YAML to improve performance when not used
var yaml = require("js-yaml");
try {
// empty YAML file can be null, so always use
return yaml.safeLoad(readFile(filePath)) || {};
} catch (e) {
debug("Error reading YAML file: " + filePath);
e.message = "Cannot read config file: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a JSON configuration from a file.
* @param {string} filePath The filename to load.
* @returns {Object} The configuration object from the file.
* @throws {Error} If the file cannot be read.
* @private
*/
function loadJSONConfigFile(filePath) {
debug("Loading JSON config file: " + filePath);
try {
return JSON.parse(stripComments(readFile(filePath)));
} catch (e) {
debug("Error reading JSON file: " + filePath);
e.message = "Cannot read config file: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a legacy (.eslintrc) configuration from a file.
* @param {string} filePath The filename to load.
* @returns {Object} The configuration object from the file.
* @throws {Error} If the file cannot be read.
* @private
*/
function loadLegacyConfigFile(filePath) {
debug("Loading config file: " + filePath);
// lazy load YAML to improve performance when not used
var yaml = require("js-yaml");
try {
return yaml.safeLoad(stripComments(readFile(filePath))) || {};
} catch (e) {
debug("Error reading YAML file: " + filePath);
e.message = "Cannot read config file: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a JavaScript configuration from a file.
* @param {string} filePath The filename to load.
* @returns {Object} The configuration object from the file.
* @throws {Error} If the file cannot be read.
* @private
*/
function loadJSConfigFile(filePath) {
debug("Loading JS config file: " + filePath);
try {
return require(filePath);
} catch (e) {
debug("Error reading JavaScript file: " + filePath);
e.message = "Cannot read config file: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a configuration from a package.json file.
* @param {string} filePath The filename to load.
* @returns {Object} The configuration object from the file.
* @throws {Error} If the file cannot be read.
* @private
*/
function loadPackageJSONConfigFile(filePath) {
debug("Loading package.json config file: " + filePath);
try {
return require(filePath).eslintConfig || null;
} catch (e) {
debug("Error reading package.json file: " + filePath);
e.message = "Cannot read config file: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a JavaScript configuration from a package.
* @param {string} filePath The package name to load.
* @returns {Object} The configuration object from the package.
* @throws {Error} If the package cannot be read.
* @private
*/
function loadPackage(filePath) {
debug("Loading config package: " + filePath);
try {
return require(filePath);
} catch (e) {
debug("Error reading package: " + filePath);
e.message = "Cannot read config package: " + filePath + "\nError: " + e.message;
throw e;
}
}
/**
* Loads a configuration file regardless of the source. Inspects the file path
* to determine the correctly way to load the config file.
* @param {string} filePath The path to the configuration.
* @returns {Object} The configuration information.
* @private
*/
function loadConfigFile(filePath) {
var config;
if (isFilePath(filePath)) {
switch (path.extname(filePath)) {
case ".js":
config = loadJSConfigFile(filePath);
break;
case ".json":
if (path.basename(filePath) === "package.json") {
config = loadPackageJSONConfigFile(filePath);
if (config === null) {
return null;
}
} else {
config = loadJSONConfigFile(filePath);
}
break;
case ".yaml":
case ".yml":
config = loadYAMLConfigFile(filePath);
break;
default:
config = loadLegacyConfigFile(filePath);
}
} else {
config = loadPackage(filePath);
}
return ConfigOps.merge(ConfigOps.createEmptyConfig(), config);
}
/**
* Writes a configuration file in JSON format.
* @param {Object} config The configuration object to write.
* @param {string} filePath The filename to write to.
* @returns {void}
* @private
*/
function writeJSONConfigFile(config, filePath) {
debug("Writing JSON config file: " + filePath);
var content = JSON.stringify(config, null, 4);
fs.writeFileSync(filePath, content, "utf8");
}
/**
* Writes a configuration file in YAML format.
* @param {Object} config The configuration object to write.
* @param {string} filePath The filename to write to.
* @returns {void}
* @private
*/
function writeYAMLConfigFile(config, filePath) {
debug("Writing YAML config file: " + filePath);
// lazy load YAML to improve performance when not used
var yaml = require("js-yaml");
var content = yaml.safeDump(config);
fs.writeFileSync(filePath, content, "utf8");
}
/**
* Writes a configuration file in JavaScript format.
* @param {Object} config The configuration object to write.
* @param {string} filePath The filename to write to.
* @returns {void}
* @private
*/
function writeJSConfigFile(config, filePath) {
debug("Writing JS config file: " + filePath);
var content = "module.exports = " + JSON.stringify(config, null, 4) + ";";
fs.writeFileSync(filePath, content, "utf8");
}
/**
* Writes a configuration file.
* @param {Object} config The configuration object to write.
* @param {string} filePath The filename to write to.
* @returns {void}
* @throws {Error} When an unknown file type is specified.
* @private
*/
function write(config, filePath) {
switch (path.extname(filePath)) {
case ".js":
writeJSConfigFile(config, filePath);
break;
case ".json":
writeJSONConfigFile(config, filePath);
break;
case ".yaml":
case ".yml":
writeYAMLConfigFile(config, filePath);
break;
default:
throw new Error("Can't write to unknown file type.");
}
}
/**
* Applies values from the "extends" field in a configuration file.
* @param {Object} config The configuration information.
* @param {string} filePath The file path from which the configuration information
* was loaded.
* @returns {Object} A new configuration object with all of the "extends" fields
* loaded and merged.
* @private
*/
function applyExtends(config, filePath) {
var configExtends = config.extends;
// normalize into an array for easier handling
if (!Array.isArray(config.extends)) {
configExtends = [config.extends];
}
// Make the last element in an array take the highest precedence
config = configExtends.reduceRight(function(previousValue, parentPath) {
if (parentPath === "eslint:recommended") {
// Add an explicit substitution for eslint:recommended to conf/eslint.json
// this lets us use the eslint.json file as the recommended rules
parentPath = path.resolve(__dirname, "../../conf/eslint.json");
} else if (isFilePath(parentPath)) {
// If the `extends` path is relative, use the directory of the current configuration
// file as the reference point. Otherwise, use as-is.
parentPath = (!isAbsolutePath(parentPath) ?
path.join(path.dirname(filePath), parentPath) :
parentPath
);
}
try {
debug("Loading " + parentPath);
return ConfigOps.merge(load(parentPath), previousValue);
} catch (e) {
// If the file referenced by `extends` failed to load, add the path to the
// configuration file that referenced it to the error message so the user is
// able to see where it was referenced from, then re-throw
e.message += "\nReferenced from: " + filePath;
throw e;
}
}, config);
return config;
}
/**
* Resolves a configuration file path into the fully-formed path, whether filename
* or package name.
* @param {string} filePath The filepath to resolve.
* @returns {string} A path that can be used directly to load the configuration.
* @private
*/
function resolve(filePath) {
if (isFilePath(filePath)) {
return path.resolve(filePath);
} else {
// it's a package
if (filePath.charAt(0) === "@") {
// it's a scoped package
// package name is "eslint-config", or just a username
var scopedPackageShortcutRegex = /^(@[^\/]+)(?:\/(?:eslint-config)?)?$/;
if (scopedPackageShortcutRegex.test(filePath)) {
filePath = filePath.replace(scopedPackageShortcutRegex, "$1/eslint-config");
} else if (filePath.split("/")[1].indexOf("eslint-config-") !== 0) {
// for scoped packages, insert the eslint-config after the first /
filePath = filePath.replace(/^@([^\/]+)\/(.*)$/, "@$1/eslint-config-$2");
}
} else if (filePath.indexOf("eslint-config-") !== 0) {
filePath = "eslint-config-" + filePath;
}
return filePath;
}
}
/**
* Loads a configuration file from the given file path.
* @param {string} filePath The filename or package name to load the configuration
* information from.
* @returns {Object} The configuration information.
* @private
*/
function load(filePath) {
var resolvedPath = resolve(filePath),
config = loadConfigFile(resolvedPath);
if (config) {
// validate the configuration before continuing
validator.validate(config, filePath);
// If an `extends` property is defined, it represents a configuration file to use as
// a "parent". Load the referenced file and merge the configuration recursively.
if (config.extends) {
config = applyExtends(config, filePath);
}
if (config.env) {
// Merge in environment-specific globals and ecmaFeatures.
config = ConfigOps.applyEnvironments(config);
}
}
return config;
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
load: load,
resolve: resolve,
write: write,
applyExtends: applyExtends,
CONFIG_FILES: CONFIG_FILES,
/**
* Retrieves the configuration filename for a given directory. It loops over all
* of the valid configuration filenames in order to find the first one that exists.
* @param {string} directory The directory to check for a config file.
* @returns {?string} The filename of the configuration file for the directory
* or null if there is no configuration file in the directory.
*/
getFilenameForDirectory: function(directory) {
var filename;
for (var i = 0, len = CONFIG_FILES.length; i < len; i++) {
filename = path.join(directory, CONFIG_FILES[i]);
if (fs.existsSync(filename)) {
return filename;
}
}
return null;
}
};

241
node_modules/eslint/lib/config/config-initializer.js generated vendored Normal file
View File

@@ -0,0 +1,241 @@
/**
* @fileoverview Config initialization wizard.
* @author Ilya Volodin
* @copyright 2015 Ilya Volodin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var exec = require("child_process").exec,
inquirer = require("inquirer"),
ConfigFile = require("./config-file");
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
/* istanbul ignore next: hard to test fs function */
/**
* Create .eslintrc file in the current working directory
* @param {object} config object that contains user's answers
* @param {string} format The file format to write to.
* @param {function} callback function to call once the file is written.
* @returns {void}
*/
function writeFile(config, format, callback) {
// default is .js
var extname = ".js";
if (format === "YAML") {
extname = ".yml";
} else if (format === "JSON") {
extname = ".json";
}
try {
ConfigFile.write(config, "./.eslintrc" + extname);
console.log("Successfully created .eslintrc" + extname + " file in " + process.cwd());
} catch (e) {
callback(e);
return;
}
// install any external configs as well as any included plugins
if (config.extends && config.extends.indexOf("eslint") === -1) {
console.log("Installing additional dependencies");
exec("npm i eslint-config-" + config.extends + " --save-dev", function(err) {
if (err) {
return callback(err);
}
// TODO: consider supporting more than 1 plugin though it's required yet.
exec("npm i eslint-plugin-" + config.plugins[0] + " --save-dev", callback);
});
return;
}
// install the react plugin if it was explictly chosen
if (config.plugins && config.plugins.indexOf("react") >= 0) {
console.log("Installing React plugin");
exec("npm i eslint-plugin-react --save-dev", callback);
return;
}
callback();
}
/**
* process user's answers and create config object
* @param {object} answers answers received from inquirer
* @returns {object} config object
*/
function processAnswers(answers) {
var config = {rules: {}, env: {}, extends: "eslint:recommended"};
config.rules.indent = [2, answers.indent];
config.rules.quotes = [2, answers.quotes];
config.rules["linebreak-style"] = [2, answers.linebreak];
config.rules.semi = [2, answers.semi ? "always" : "never"];
if (answers.es6) {
config.env.es6 = true;
}
answers.env.forEach(function(env) {
config.env[env] = true;
});
if (answers.jsx) {
config.ecmaFeatures = {jsx: true};
if (answers.react) {
config.plugins = ["react"];
config.ecmaFeatures.experimentalObjectRestSpread = true;
}
}
return config;
}
/**
* process user's style guide of choice and return an appropriate config object.
* @param {string} guide name of the chosen style guide
* @returns {object} config object
*/
function getConfigForStyleGuide(guide) {
var guides = {
google: {extends: "google"},
airbnb: {extends: "airbnb", plugins: ["react"]},
standard: {extends: "standard", plugins: ["standard"]}
};
if (!guides[guide]) {
throw new Error("You referenced an unsupported guide.");
}
return guides[guide];
}
/* istanbul ignore next: no need to test inquirer*/
/**
* Ask use a few questions on command prompt
* @param {function} callback callback function when file has been written
* @returns {void}
*/
function promptUser(callback) {
inquirer.prompt([
{
type: "list",
name: "source",
message: "How would you like to configure ESLint?",
default: "prompt",
choices: [{name: "Answer questions about your style", value: "prompt"}, {name: "Use a popular style guide", value: "guide"}]
},
{
type: "list",
name: "styleguide",
message: "Which style guide do you want to follow?",
choices: [{name: "Google", value: "google"}, {name: "AirBnB", value: "airbnb"}, {name: "Standard", value: "standard"}],
when: function(answers) {
return answers.source === "guide";
}
},
{
type: "list",
name: "format",
message: "What format do you want your config file to be in?",
default: "JavaScript",
choices: ["JavaScript", "YAML", "JSON"],
when: function(answers) {
return answers.source === "guide";
}
}
], function(earlyAnswers) {
// early exit if you are using a style guide
if (earlyAnswers.source === "guide") {
writeFile(getConfigForStyleGuide(earlyAnswers.styleguide), earlyAnswers.format, callback);
return;
}
// continue with the style questions otherwise...
inquirer.prompt([
{
type: "list",
name: "indent",
message: "What style of indentation do you use?",
default: "tabs",
choices: [{name: "Tabs", value: "tab"}, {name: "Spaces", value: 4}]
},
{
type: "list",
name: "quotes",
message: "What quotes do you use for strings?",
default: "double",
choices: [{name: "Double", value: "double"}, {name: "Single", value: "single"}]
},
{
type: "list",
name: "linebreak",
message: "What line endings do you use?",
default: "unix",
choices: [{name: "Unix", value: "unix"}, {name: "Windows", value: "windows"}]
},
{
type: "confirm",
name: "semi",
message: "Do you require semicolons?",
default: true
},
{
type: "confirm",
name: "es6",
message: "Are you using ECMAScript 6 features?",
default: false
},
{
type: "checkbox",
name: "env",
message: "Where will your code run?",
default: ["browser"],
choices: [{name: "Node", value: "node"}, {name: "Browser", value: "browser"}]
},
{
type: "confirm",
name: "jsx",
message: "Do you use JSX?",
default: false
},
{
type: "confirm",
name: "react",
message: "Do you use React",
default: false,
when: function(answers) {
return answers.jsx;
}
},
{
type: "list",
name: "format",
message: "What format do you want your config file to be in?",
default: "JavaScript",
choices: ["JavaScript", "YAML", "JSON"]
}
], function(answers) {
var config = processAnswers(answers);
writeFile(config, answers.format, callback);
});
});
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
var init = {
getConfigForStyleGuide: getConfigForStyleGuide,
processAnswers: processAnswers,
initializeConfig: /* istanbul ignore next */ function(callback) {
promptUser(callback);
}
};
module.exports = init;

186
node_modules/eslint/lib/config/config-ops.js generated vendored Normal file
View File

@@ -0,0 +1,186 @@
/**
* @fileoverview Config file operations. This file must be usable in the browser,
* so no Node-specific code can be here.
* @author Nicholas C. Zakas
* @copyright 2015 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var debug = require("debug"),
environments = require("../../conf/environments"),
assign = require("object-assign");
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
debug = debug("eslint:config-ops");
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
/**
* Creates an empty configuration object suitable for merging as a base.
* @returns {Object} A configuration object.
*/
createEmptyConfig: function() {
return {
globals: {},
env: {},
rules: {},
ecmaFeatures: {}
};
},
/**
* Creates an environment config based on the specified environments.
* @param {Object<string,boolean>} env The environment settings.
* @returns {Object} A configuration object with the appropriate rules and globals
* set.
*/
createEnvironmentConfig: function(env) {
var envConfig = this.createEmptyConfig();
if (env) {
envConfig.env = env;
Object.keys(env).filter(function(name) {
return env[name];
}).forEach(function(name) {
var environment = environments[name];
if (environment) {
debug("Creating config for environment " + name);
if (environment.globals) {
assign(envConfig.globals, environment.globals);
}
if (environment.ecmaFeatures) {
assign(envConfig.ecmaFeatures, environment.ecmaFeatures);
}
}
});
}
return envConfig;
},
/**
* Given a config with environment settings, applies the globals and
* ecmaFeatures to the configuration and returns the result.
* @param {Object} config The configuration information.
* @returns {Object} The updated configuration information.
*/
applyEnvironments: function(config) {
if (config.env && typeof config.env === "object") {
debug("Apply environment settings to config");
return this.merge(this.createEnvironmentConfig(config.env), config);
}
return config;
},
/**
* Merges two config objects. This will not only add missing keys, but will also modify values to match.
* @param {Object} target config object
* @param {Object} src config object. Overrides in this config object will take priority over base.
* @param {boolean} [combine] Whether to combine arrays or not
* @param {boolean} [isRule] Whether its a rule
* @returns {Object} merged config object.
*/
merge: function deepmerge(target, src, combine, isRule) {
/*
The MIT License (MIT)
Copyright (c) 2012 Nicholas Fisher
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
// This code is taken from deepmerge repo (https://github.com/KyleAMathews/deepmerge) and modified to meet our needs.
var array = Array.isArray(src) || Array.isArray(target);
var dst = array && [] || {};
combine = !!combine;
isRule = !!isRule;
if (array) {
target = target || [];
if (isRule && src.length > 1) {
dst = dst.concat(src);
} else {
dst = dst.concat(target);
}
if (typeof src !== "object" && !Array.isArray(src)) {
src = [src];
}
Object.keys(src).forEach(function(e, i) {
e = src[i];
if (typeof dst[i] === "undefined") {
dst[i] = e;
} else if (typeof e === "object") {
if (isRule) {
dst[i] = e;
} else {
dst[i] = deepmerge(target[i], e, combine, isRule);
}
} else {
if (!combine) {
dst[i] = e;
} else {
if (dst.indexOf(e) === -1) {
dst.push(e);
}
}
}
});
} else {
if (target && typeof target === "object") {
Object.keys(target).forEach(function(key) {
dst[key] = target[key];
});
}
Object.keys(src).forEach(function(key) {
if (Array.isArray(src[key]) || Array.isArray(target[key])) {
dst[key] = deepmerge(target[key], src[key], key === "plugins", isRule);
} else if (typeof src[key] !== "object" || !src[key]) {
dst[key] = src[key];
} else {
if (!target[key]) {
dst[key] = src[key];
} else {
dst[key] = deepmerge(target[key], src[key], combine, key === "rules");
}
}
});
}
return dst;
}
};

163
node_modules/eslint/lib/config/config-validator.js generated vendored Normal file
View File

@@ -0,0 +1,163 @@
/**
* @fileoverview Validates configs.
* @author Brandon Mills
* @copyright 2015 Brandon Mills
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var rules = require("../rules"),
environments = require("../../conf/environments"),
schemaValidator = require("is-my-json-valid");
var validators = {
rules: Object.create(null)
};
//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------
/**
* Gets a complete options schema for a rule.
* @param {string} id The rule's unique name.
* @returns {object} JSON Schema for the rule's options.
*/
function getRuleOptionsSchema(id) {
var rule = rules.get(id),
schema = rule && rule.schema;
if (!schema) {
return {
"type": "array",
"items": [
{
"enum": [0, 1, 2]
}
],
"minItems": 1
};
}
// Given a tuple of schemas, insert warning level at the beginning
if (Array.isArray(schema)) {
return {
"type": "array",
"items": [
{
"enum": [0, 1, 2]
}
].concat(schema),
"minItems": 1,
"maxItems": schema.length + 1
};
}
// Given a full schema, leave it alone
return schema;
}
/**
* Validates a rule's options against its schema.
* @param {string} id The rule's unique name.
* @param {array|number} options The given options for the rule.
* @param {string} source The name of the configuration source.
* @returns {void}
*/
function validateRuleOptions(id, options, source) {
var validateRule = validators.rules[id],
message;
if (!validateRule) {
validateRule = schemaValidator(getRuleOptionsSchema(id), { verbose: true });
validators.rules[id] = validateRule;
}
if (typeof options === "number") {
options = [options];
}
validateRule(options);
if (validateRule.errors) {
message = [
source, ":\n",
"\tConfiguration for rule \"", id, "\" is invalid:\n"
];
validateRule.errors.forEach(function(error) {
if (error.field === "data[\"0\"]") { // better error for severity
message.push(
"\tSeverity should be one of the following: 0 = off, 1 = warning, 2 = error (you passed \"", error.value, "\").\n");
} else {
message.push(
"\tValue \"", error.value, "\" ", error.message, ".\n"
);
}
});
throw new Error(message.join(""));
}
}
/**
* Validates an environment object
* @param {object} environment The environment config object to validate.
* @param {string} source The location to report with any errors.
* @returns {void}
*/
function validateEnvironment(environment, source) {
// not having an environment is ok
if (!environment) {
return;
}
if (Array.isArray(environment)) {
throw new Error("Environment must not be an array");
}
if (typeof environment === "object") {
Object.keys(environment).forEach(function(env) {
if (!environments[env]) {
var message = [
source, ":\n",
"\tEnvironment key \"", env, "\" is unknown\n"
];
throw new Error(message.join(""));
}
});
} else {
throw new Error("Environment must be an object");
}
}
/**
* Validates an entire config object.
* @param {object} config The config object to validate.
* @param {string} source The location to report with any errors.
* @returns {void}
*/
function validate(config, source) {
if (typeof config.rules === "object") {
Object.keys(config.rules).forEach(function(id) {
validateRuleOptions(id, config.rules[id], source);
});
}
validateEnvironment(config.env, source);
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = {
getRuleOptionsSchema: getRuleOptionsSchema,
validate: validate,
validateRuleOptions: validateRuleOptions
};

1043
node_modules/eslint/lib/eslint.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

186
node_modules/eslint/lib/file-finder.js generated vendored Normal file
View File

@@ -0,0 +1,186 @@
/**
* @fileoverview Util class to find config files.
* @author Aliaksei Shytkin
* @copyright 2014 Michael McLaughlin. All rights reserved.
* @copyright 2014 Aliaksei Shytkin. All rights reserved.
* See LICENSE in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var fs = require("fs"),
path = require("path");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Get the entries for a directory. Including a try-catch may be detrimental to
* function performance, so move it out here a separate function.
* @param {string} directory The directory to search in.
* @returns {string[]} The entries in the directory or an empty array on error.
* @private
*/
function getDirectoryEntries(directory) {
try {
return fs.readdirSync(directory);
} catch (ex) {
return [];
}
}
//------------------------------------------------------------------------------
// API
//------------------------------------------------------------------------------
/**
* FileFinder
* @constructor
* @param {...string} arguments The basename(s) of the file(s) to find.
*/
function FileFinder() {
this.fileNames = Array.prototype.slice.call(arguments);
this.cache = {};
}
/**
* Find one instance of a specified file name in directory or in a parent directory.
* Cache the results.
* Does not check if a matching directory entry is a file, and intentionally
* only searches for the first file name in this.fileNames.
* Is currently used by lib/ignored_paths.js to find an .eslintignore file.
* @param {string} directory The directory to start the search from.
* @returns {string} Path of the file found, or an empty string if not found.
*/
FileFinder.prototype.findInDirectoryOrParents = function(directory) {
var cache = this.cache,
child,
dirs,
filePath,
i,
name,
names,
searched;
if (!directory) {
directory = process.cwd();
}
if (cache.hasOwnProperty(directory)) {
return cache[directory];
}
dirs = [];
searched = 0;
name = this.fileNames[0];
names = Array.isArray(name) ? name : [name];
(function() {
while (directory !== child) {
dirs[searched++] = directory;
for (var k = 0, found = false; k < names.length && !found; k++) {
if (getDirectoryEntries(directory).indexOf(names[k]) !== -1 && fs.statSync(path.resolve(directory, names[k])).isFile()) {
filePath = path.resolve(directory, names[k]);
return;
}
}
child = directory;
// Assign parent directory to directory.
directory = path.dirname(directory);
}
}());
for (i = 0; i < searched; i++) {
cache[dirs[i]] = filePath;
}
return filePath || String();
};
/**
* Find all instances of files with the specified file names, in directory and
* parent directories. Cache the results.
* Does not check if a matching directory entry is a file.
* Searches for all the file names in this.fileNames.
* Is currently used by lib/config.js to find .eslintrc and package.json files.
* @param {string} directory The directory to start the search from.
* @returns {string[]} The file paths found.
*/
FileFinder.prototype.findAllInDirectoryAndParents = function(directory) {
var cache = this.cache,
child,
dirs,
name,
fileNames,
fileNamesCount,
filePath,
i,
j,
searched;
if (!directory) {
directory = process.cwd();
}
if (cache.hasOwnProperty(directory)) {
return cache[directory];
}
dirs = [];
searched = 0;
fileNames = this.fileNames;
fileNamesCount = fileNames.length;
do {
dirs[searched++] = directory;
cache[directory] = [];
for (i = 0; i < fileNamesCount; i++) {
name = fileNames[i];
// convert to an array for easier handling
if (!Array.isArray(name)) {
name = [name];
}
for (var k = 0, found = false; k < name.length && !found; k++) {
if (getDirectoryEntries(directory).indexOf(name[k]) !== -1 && fs.statSync(path.resolve(directory, name[k])).isFile()) {
filePath = path.resolve(directory, name[k]);
found = true;
// Add the file path to the cache of each directory searched.
for (j = 0; j < searched; j++) {
cache[dirs[j]].push(filePath);
}
}
}
}
child = directory;
// Assign parent directory to directory.
directory = path.dirname(directory);
if (directory === child) {
return cache[dirs[0]];
}
} while (!cache.hasOwnProperty(directory));
// Add what has been cached previously to the cache of each directory searched.
for (i = 0; i < searched; i++) {
dirs.push.apply(cache[dirs[i]], cache[directory]);
}
return cache[dirs[0]];
};
module.exports = FileFinder;

81
node_modules/eslint/lib/formatters/checkstyle.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
/**
* @fileoverview CheckStyle XML reporter
* @author Ian Christian Myers
*/
"use strict";
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
/**
* Returns the severity of warning or error
* @param {object} message message object to examine
* @returns {string} severity level
* @private
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return "error";
} else {
return "warning";
}
}
/**
* Returns the escaped value for a character
* @param {string} s string to examine
* @returns {string} severity level
* @private
*/
function xmlEscape(s) {
return ("" + s).replace(/[<>&"']/g, function(c) {
switch (c) {
case "<":
return "&lt;";
case ">":
return "&gt;";
case "&":
return "&amp;";
case "\"":
return "&quot;";
case "'":
return "&apos;";
// no default
}
});
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "";
output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
output += "<checkstyle version=\"4.3\">";
results.forEach(function(result) {
var messages = result.messages;
output += "<file name=\"" + xmlEscape(result.filePath) + "\">";
messages.forEach(function(message) {
output += "<error line=\"" + xmlEscape(message.line) + "\" " +
"column=\"" + xmlEscape(message.column) + "\" " +
"severity=\"" + xmlEscape(getMessageType(message)) + "\" " +
"message=\"" + xmlEscape(message.message) +
(message.ruleId ? " (" + message.ruleId + ")" : "") + "\" " +
"source=\"" + (message.ruleId ? xmlEscape("eslint.rules." + message.ruleId) : "") + "\" />";
});
output += "</file>";
});
output += "</checkstyle>";
return output;
};

59
node_modules/eslint/lib/formatters/compact.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
/**
* @fileoverview Compact reporter
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
/**
* Returns the severity of warning or error
* @param {object} message message object to examine
* @returns {string} severity level
* @private
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return "Error";
} else {
return "Warning";
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "",
total = 0;
results.forEach(function(result) {
var messages = result.messages;
total += messages.length;
messages.forEach(function(message) {
output += result.filePath + ": ";
output += "line " + (message.line || 0);
output += ", col " + (message.column || 0);
output += ", " + getMessageType(message);
output += " - " + message.message;
output += message.ruleId ? " (" + message.ruleId + ")" : "";
output += "\n";
});
});
if (total > 0) {
output += "\n" + total + " problem" + (total !== 1 ? "s" : "");
}
return output;
};

130
node_modules/eslint/lib/formatters/html-template.html generated vendored Normal file
View File

@@ -0,0 +1,130 @@
<!DOCTYPE html>
<head>
<title>ESLint Report</title>
<style>
body {
font-family:Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size:16px;
font-weight:normal;
margin:0;
padding:0;
color:#333
}
#overview {
padding:20px 30px
}
td, th {
padding:5px 10px
}
h1 {
margin:0
}
table {
margin:30px;
width:calc(100% - 60px);
max-width:1000px;
border-radius:5px;
border:1px solid #ddd;
border-spacing:0px;
}
th {
font-weight:400;
font-size:normal;
text-align:left;
cursor:pointer
}
td.clr-1, td.clr-2, th span {
font-weight:700
}
th span {
float:right;
margin-left:20px
}
th span:after {
content:"";
clear:both;
display:block
}
tr:last-child td {
border-bottom:none
}
tr td:first-child, tr td:last-child {
color:#9da0a4
}
#overview.bg-0, tr.bg-0 th {
color:#468847;
background:#dff0d8;
border-bottom:1px solid #d6e9c6
}
#overview.bg-1, tr.bg-1 th {
color:#f0ad4e;
background:#fcf8e3;
border-bottom:1px solid #fbeed5
}
#overview.bg-2, tr.bg-2 th {
color:#b94a48;
background:#f2dede;
border-bottom:1px solid #eed3d7
}
td {
border-bottom:1px solid #ddd
}
td.clr-1 {
color:#f0ad4e
}
td.clr-2 {
color:#b94a48
}
td a {
color:#3a33d1;
text-decoration:none
}
td a:hover {
color:#272296;
text-decoration:underline
}
</style>
</head>
<body>
<div id="overview" class="bg-{{getColor totalErrors totalWarnings}}">
<h1>ESLint Report</h1>
<div>
<span>{{renderText totalErrors totalWarnings}}</span> - Generated on {{date}}
</div>
</div>
<table>
<tbody>
{{#each results}}
<tr class="bg-{{getColor this.errorCount this.warningCount}}" data-group="f-{{@index}}">
<th colspan="4">
[+] {{this.filePath}}
<span>{{renderText this.errorCount this.warningCount}}</span>
</th>
</tr>
{{#each this.messages}}
<tr class="f-{{@../index}}" style="display:none">
<td>{{#if this.line}}{{this.line}}{{else}}0{{/if}}:{{#if this.column}}{{this.column}}{{else}}0{{/if}}</td>
{{getSeverity this.severity}}
<td>{{this.message}}</td>
<td>
<a href="http://eslint.org/docs/rules/{{this.ruleId}}" target="_blank">{{this.ruleId}}</a>
</td>
</tr>
{{/each}}
{{/each}}
</tbody>
</table>
<script type="text/javascript">
var groups = document.querySelectorAll("tr[data-group]");
for (i = 0; i < groups.length; i++) {
groups[i].addEventListener("click", function() {
var inGroup = document.getElementsByClassName(this.getAttribute("data-group"));
this.innerHTML = (this.innerHTML.indexOf("+") > -1) ? this.innerHTML.replace("+", "-") : this.innerHTML.replace("-", "+");
for (var j = 0; j < inGroup.length; j++) {
inGroup[j].style.display = (inGroup[j].style.display !== "none") ? "none" : "table-row";
}
});
}
</script>
</body>
</html>

88
node_modules/eslint/lib/formatters/html.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/**
* @fileoverview HTML reporter
* @author Julian Laval
* @copyright 2015 Julian Laval. All rights reserved.
*/
"use strict";
var handlebars = require("handlebars").create();
var fs = require("fs");
var path = require("path");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Given a word and a count, append an s if count is not one.
* @param {string} word A word in its singular form.
* @param {int} count A number controlling whether word should be pluralized.
* @returns {string} The original word with an s on the end if count is not one.
*/
function pluralize(word, count) {
return (count === 1 ? word : word + "s");
}
/**
* Renders text along the template of x problems (x errors, x warnings)
* @param {string} totalErrors Total errors
* @param {string} totalWarnings Total warnings
* @returns {string} The formatted string, pluralized where necessary
*/
handlebars.registerHelper("renderText", function(totalErrors, totalWarnings) {
var totalProblems = totalErrors + totalWarnings;
var renderedText = totalProblems + " " + pluralize("problem", totalProblems);
if (totalProblems !== 0) {
renderedText += " (" + totalErrors + " " + pluralize("error", totalErrors) + ", " + totalWarnings + " " + pluralize("warning", totalWarnings) + ")";
}
return renderedText;
});
/**
* Get the color based on whether there are errors/warnings...
* @param {string} totalErrors Total errors
* @param {string} totalWarnings Total warnings
* @returns {int} The color code (0 = green, 1 = yellow, 2 = red)
*/
handlebars.registerHelper("getColor", function(totalErrors, totalWarnings) {
if (totalErrors !== 0) {
return 2;
} else if (totalWarnings !== 0) {
return 1;
}
return 0;
});
/**
* Get the HTML row content based on the severity of the message
* @param {int} severity Severity of the message
* @returns {string} The generated HTML row
*/
handlebars.registerHelper("getSeverity", function(severity) {
// Return warning else error
return new handlebars.SafeString((severity === 1) ? "<td class=\"clr-1\">Warning</td>" : "<td class=\"clr-2\">Error</td>");
});
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var template = fs.readFileSync(path.join(__dirname, "html-template.html"), "utf-8");
var data = {
date: new Date(),
totalErrors: 0,
totalWarnings: 0,
results: results
};
// Iterate over results to get totals
results.forEach(function(result) {
data.totalErrors += result.errorCount;
data.totalWarnings += result.warningCount;
});
return handlebars.compile(template)(data);
};

40
node_modules/eslint/lib/formatters/jslint-xml.js generated vendored Normal file
View File

@@ -0,0 +1,40 @@
/**
* @fileoverview JSLint XML reporter
* @author Ian Christian Myers
*/
"use strict";
var xmlescape = require("xml-escape");
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "";
output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
output += "<jslint>";
results.forEach(function(result) {
var messages = result.messages;
output += "<file name=\"" + result.filePath + "\">";
messages.forEach(function(message) {
output += "<issue line=\"" + message.line + "\" " +
"char=\"" + message.column + "\" " +
"evidence=\"" + xmlescape(message.source || "") + "\" " +
"reason=\"" + xmlescape(message.message || "") +
(message.ruleId ? " (" + message.ruleId + ")" : "") + "\" />";
});
output += "</file>";
});
output += "</jslint>";
return output;
};

14
node_modules/eslint/lib/formatters/json.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
/**
* @fileoverview JSON reporter
* @author Burak Yigit Kaya aka BYK
* @copyright 2015 Burak Yigit Kaya. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
return JSON.stringify(results);
};

69
node_modules/eslint/lib/formatters/junit.js generated vendored Normal file
View File

@@ -0,0 +1,69 @@
/**
* @fileoverview jUnit Reporter
* @author Jamund Ferguson
*/
"use strict";
var xmlescape = require("xml-escape");
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
/**
* Returns the severity of warning or error
* @param {object} message message object to examine
* @returns {string} severity level
* @private
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return "Error";
} else {
return "Warning";
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "";
output += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
output += "<testsuites>\n";
results.forEach(function(result) {
var messages = result.messages;
if (messages.length) {
output += "<testsuite package=\"org.eslint\" time=\"0\" tests=\"" + messages.length + "\" errors=\"" + messages.length + "\" name=\"" + result.filePath + "\">\n";
}
messages.forEach(function(message) {
var type = message.fatal ? "error" : "failure";
output += "<testcase time=\"0\" name=\"org.eslint." + (message.ruleId || "unknown") + "\">";
output += "<" + type + " message=\"" + xmlescape(message.message || "") + "\">";
output += "<![CDATA[";
output += "line " + (message.line || 0) + ", col ";
output += (message.column || 0) + ", " + getMessageType(message);
output += " - " + xmlescape(message.message || "");
output += (message.ruleId ? " (" + message.ruleId + ")" : "");
output += "]]>";
output += "</" + type + ">";
output += "</testcase>\n";
});
if (messages.length) {
output += "</testsuite>\n";
}
});
output += "</testsuites>\n";
return output;
};

90
node_modules/eslint/lib/formatters/stylish.js generated vendored Normal file
View File

@@ -0,0 +1,90 @@
/**
* @fileoverview Stylish reporter
* @author Sindre Sorhus
*/
"use strict";
var chalk = require("chalk"),
table = require("text-table");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Given a word and a count, append an s if count is not one.
* @param {string} word A word in its singular form.
* @param {int} count A number controlling whether word should be pluralized.
* @returns {string} The original word with an s on the end if count is not one.
*/
function pluralize(word, count) {
return (count === 1 ? word : word + "s");
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "\n",
total = 0,
errors = 0,
warnings = 0,
summaryColor = "yellow";
results.forEach(function(result) {
var messages = result.messages;
if (messages.length === 0) {
return;
}
total += messages.length;
output += chalk.underline(result.filePath) + "\n";
output += table(
messages.map(function(message) {
var messageType;
if (message.fatal || message.severity === 2) {
messageType = chalk.red("error");
summaryColor = "red";
errors++;
} else {
messageType = chalk.yellow("warning");
warnings++;
}
return [
"",
message.line || 0,
message.column || 0,
messageType,
message.message.replace(/\.$/, ""),
chalk.gray(message.ruleId || "")
];
}),
{
align: ["", "r", "l"],
stringLength: function(str) {
return chalk.stripColor(str).length;
}
}
).split("\n").map(function(el) {
return el.replace(/(\d+)\s+(\d+)/, function(m, p1, p2) {
return chalk.gray(p1 + ":" + p2);
});
}).join("\n") + "\n\n";
});
if (total > 0) {
output += chalk[summaryColor].bold([
"\u2716 ", total, pluralize(" problem", total),
" (", errors, pluralize(" error", errors), ", ",
warnings, pluralize(" warning", warnings), ")\n"
].join(""));
}
return total > 0 ? output : "";
};

86
node_modules/eslint/lib/formatters/tap.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
/**
* @fileoverview TAP reporter
* @author Jonathan Kingston
*/
"use strict";
var yaml = require("js-yaml");
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
/**
* Returns a canonical error level string based upon the error message passed in.
* @param {object} message Individual error message provided by eslint
* @returns {String} Error level string
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return "error";
} else {
return "warning";
}
}
/**
* Takes in a JavaScript object and outputs a TAP diagnostics string
* @param {object} diagnostic JavaScript object to be embedded as YAML into output.
* @returns {string} diagnostics string with YAML embedded - TAP version 13 compliant
*/
function outputDiagnostics(diagnostic) {
var prefix = " ";
var output = prefix + "---\n";
output += prefix + yaml.safeDump(diagnostic).split("\n").join("\n" + prefix);
output += "...\n";
return output;
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "TAP version 13\n1.." + results.length + "\n";
results.forEach(function(result, id) {
var messages = result.messages;
var testResult = "ok";
var diagnostics = {};
if (messages.length > 0) {
testResult = "not ok";
messages.forEach(function(message) {
var diagnostic = {
message: message.message,
severity: getMessageType(message),
data: {
line: message.line || 0,
column: message.column || 0,
ruleId: message.ruleId || ""
}
};
// If we have multiple messages place them under a messages key
// The first error will be logged as message key
// This is to adhere to TAP 13 loosely defined specification of having a message key
if ("message" in diagnostics) {
diagnostics.messages = [diagnostic];
} else {
diagnostics = diagnostic;
}
});
}
output += testResult + " " + (id + 1) + " - " + result.filePath + "\n";
// If we have an error include diagnostics
if (messages.length > 0) {
output += outputDiagnostics(diagnostics);
}
});
return output;
};

59
node_modules/eslint/lib/formatters/unix.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
/**
* @fileoverview unix-style formatter.
* @author oshi-shinobu
* @copyright 2015 oshi-shinobu. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Helper Functions
//------------------------------------------------------------------------------
/**
* Returns a canonical error level string based upon the error message passed in.
* @param {object} message Individual error message provided by eslint
* @returns {String} Error level string
*/
function getMessageType(message) {
if (message.fatal || message.severity === 2) {
return "Error";
} else {
return "Warning";
}
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
module.exports = function(results) {
var output = "",
total = 0;
results.forEach(function(result) {
var messages = result.messages;
total += messages.length;
messages.forEach(function(message) {
output += result.filePath + ":";
output += (message.line || 0) + ":";
output += (message.column || 0) + ":";
output += " " + message.message + " ";
output += "[" + getMessageType(message) +
(message.ruleId ? "/" + message.ruleId : "") + "]";
output += "\n";
});
});
if (total > 0) {
output += "\n" + total + " problem" + (total !== 1 ? "s" : "");
}
return output;
};

143
node_modules/eslint/lib/ignored-paths.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
/**
* @fileoverview Responsible for loading ignore config files and managing ignore patterns
* @author Jonathan Rajavuori
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var fs = require("fs"),
debug = require("debug"),
minimatch = require("minimatch"),
FileFinder = require("./file-finder");
debug = debug("eslint:ignored-paths");
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var ESLINT_IGNORE_FILENAME = ".eslintignore";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Load and parse ignore patterns from the file at the given path
* @param {string} filepath Path to the ignore file.
* @returns {string[]} An array of ignore patterns or an empty array if no ignore file.
*/
function loadIgnoreFile(filepath) {
var ignorePatterns = [];
/**
* Check if string is not empty
* @param {string} line string to examine
* @returns {boolean} True is its not empty
* @private
*/
function nonEmpty(line) {
return line.trim() !== "" && line[0] !== "#";
}
if (filepath) {
try {
ignorePatterns = fs.readFileSync(filepath, "utf8").split(/\r?\n/).filter(nonEmpty);
} catch (e) {
e.message = "Cannot read ignore file: " + filepath + "\nError: " + e.message;
throw e;
}
}
return ["node_modules/**"].concat(ignorePatterns);
}
var ignoreFileFinder;
/**
* Find an ignore file in the current directory or a parent directory.
* @returns {string} Path of ignore file or an empty string.
*/
function findIgnoreFile() {
if (!ignoreFileFinder) {
ignoreFileFinder = new FileFinder(ESLINT_IGNORE_FILENAME);
}
return ignoreFileFinder.findInDirectoryOrParents();
}
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* IgnoredPaths
* @constructor
* @class IgnoredPaths
* @param {Array} patterns to be matched against file paths
*/
function IgnoredPaths(patterns) {
this.patterns = patterns;
}
/**
* IgnoredPaths initializer
* @param {Object} options object containing 'ignore' and 'ignorePath' properties
* @returns {IgnoredPaths} object, with patterns loaded from the ignore file
*/
IgnoredPaths.load = function(options) {
var patterns;
options = options || {};
if (options.ignore) {
patterns = loadIgnoreFile(options.ignorePath || findIgnoreFile());
} else {
patterns = [];
}
if (options.ignorePattern) {
patterns = patterns.concat(options.ignorePattern);
}
return new IgnoredPaths(patterns);
};
/**
* Determine whether a file path is included in the configured ignore patterns
* @param {string} filepath Path to check
* @returns {boolean} true if the file path matches one or more patterns, false otherwise
*/
IgnoredPaths.prototype.contains = function(filepath) {
if (this.patterns === null) {
throw new Error("No ignore patterns loaded, call 'load' first");
}
filepath = filepath.replace("\\", "/");
filepath = filepath.replace(/^\.\//, "");
return this.patterns.reduce(function(ignored, pattern) {
var negated = pattern[0] === "!",
matches;
if (negated) {
pattern = pattern.slice(1);
}
// Remove leading "current folder" prefix
if (pattern.indexOf("./") === 0) {
pattern = pattern.slice(2);
}
matches = minimatch(filepath, pattern) || minimatch(filepath, pattern + "/**");
return matches ? !negated : ignored;
}, false);
};
module.exports = IgnoredPaths;

39
node_modules/eslint/lib/load-rules.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
/**
* @fileoverview Module for loading rules from files and directories.
* @author Michael Ficarra
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var fs = require("fs"),
path = require("path");
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* Load all rule modules from specified directory.
* @param {String} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`.
* @returns {Object} Loaded rule modules by rule ids (file names).
*/
module.exports = function(rulesDir) {
if (!rulesDir) {
rulesDir = path.join(__dirname, "rules");
} else {
rulesDir = path.resolve(process.cwd(), rulesDir);
}
var rules = Object.create(null);
fs.readdirSync(rulesDir).forEach(function(file) {
if (path.extname(file) !== ".js") {
return;
}
rules[file.slice(0, -3)] = path.join(rulesDir, file);
});
return rules;
};

25
node_modules/eslint/lib/logging.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/**
* @fileoverview Handle logging for Eslint
* @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/
"use strict";
/* istanbul ignore next */
module.exports = {
/**
* Cover for console.log
* @returns {void}
*/
info: function() {
console.log.apply(console, Array.prototype.slice.call(arguments));
},
/**
* Cover for console.error
* @returns {void}
*/
error: function() {
console.error.apply(console, Array.prototype.slice.call(arguments));
}
};

209
node_modules/eslint/lib/options.js generated vendored Normal file
View File

@@ -0,0 +1,209 @@
/**
* @fileoverview Options configuration for optionator.
* @author George Zahariev
* See LICENSE in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var optionator = require("optionator");
//------------------------------------------------------------------------------
// Initialization and Public Interface
//------------------------------------------------------------------------------
// exports "parse(args)", "generateHelp()", and "generateHelpForOption(optionName)"
module.exports = optionator({
prepend: "eslint [options] file.js [file.js] [dir]",
concatRepeatedArrays: true,
mergeRepeatedObjects: true,
options: [
{
heading: "Basic configuration"
},
{
option: "config",
alias: "c",
type: "path::String",
description: "Use configuration from this file or shareable config"
},
{
option: "eslintrc",
type: "Boolean",
default: "true",
description: "Disable use of configuration from .eslintrc"
},
{
option: "env",
type: "[String]",
description: "Specify environments"
},
{
option: "ext",
type: "[String]",
default: ".js",
description: "Specify JavaScript file extensions"
},
{
option: "global",
type: "[String]",
description: "Define global variables"
},
{
option: "parser",
type: "String",
default: "espree",
description: "Specify the parser to be used"
},
{
heading: "Caching"
},
{
option: "cache",
type: "Boolean",
default: "false",
description: "Only check changed files"
},
{
option: "cache-file",
type: "path::String",
default: ".eslintcache",
description: "Path to the cache file. Deprecated: use --cache-location"
},
{
option: "cache-location",
type: "path::String",
description: "Path to the cache file or directory"
},
{
heading: "Specifying rules and plugins"
},
{
option: "rulesdir",
type: "[path::String]",
description: "Use additional rules from this directory"
},
{
option: "plugin",
type: "[String]",
description: "Specify plugins"
},
{
option: "rule",
type: "Object",
description: "Specify rules"
},
{
heading: "Ignoring files"
},
{
option: "ignore-path",
type: "path::String",
description: "Specify path of ignore file"
},
{
option: "ignore",
type: "Boolean",
default: "true",
description: "Disable use of .eslintignore"
},
{
option: "ignore-pattern",
type: "[String]",
description: "Pattern of files to ignore (in addition to those in .eslintignore)"
},
{
heading: "Using stdin"
},
{
option: "stdin",
type: "Boolean",
default: "false",
description: "Lint code provided on <STDIN>"
},
{
option: "stdin-filename",
type: "String",
description: "Specify filename to process STDIN as"
},
{
heading: "Handling warnings"
},
{
option: "quiet",
type: "Boolean",
default: "false",
description: "Report errors only"
},
{
option: "max-warnings",
type: "Number",
default: "-1",
description: "Number of warnings to trigger nonzero exit code"
},
{
heading: "Output"
},
{
option: "output-file",
alias: "o",
type: "path::String",
description: "Specify file to write report to"
},
{
option: "format",
alias: "f",
type: "String",
default: "stylish",
description: "Use a specific output format"
},
{
option: "color",
type: "Boolean",
default: "true",
description: "Disable color in piped output"
},
{
heading: "Miscellaneous"
},
{
option: "init",
type: "Boolean",
default: "false",
description: "Run config initialization wizard"
},
{
option: "fix",
type: "Boolean",
default: false,
description: "Automatically fix problems"
},
{
option: "debug",
type: "Boolean",
default: false,
description: "Output debugging information"
},
{
option: "help",
alias: "h",
type: "Boolean",
description: "Show help"
},
{
option: "version",
alias: "v",
type: "Boolean",
description: "Outputs the version number"
},
{
option: "inline-config",
type: "Boolean",
default: "true",
description: "Allow comments to change eslint config/rules"
}
]
});

163
node_modules/eslint/lib/rule-context.js generated vendored Normal file
View File

@@ -0,0 +1,163 @@
/**
* @fileoverview RuleContext utility for rules
* @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var RuleFixer = require("./util/rule-fixer");
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var PASSTHROUGHS = [
"getAllComments",
"getAncestors",
"getComments",
"getDeclaredVariables",
"getFilename",
"getFirstToken",
"getFirstTokens",
"getJSDocComment",
"getLastToken",
"getLastTokens",
"getNodeByRangeIndex",
"getScope",
"getSource",
"getSourceLines",
"getTokenAfter",
"getTokenBefore",
"getTokenByRangeStart",
"getTokens",
"getTokensAfter",
"getTokensBefore",
"getTokensBetween",
"markVariableAsUsed",
"isMarkedAsUsed"
];
//------------------------------------------------------------------------------
// Typedefs
//------------------------------------------------------------------------------
/**
* An error message description
* @typedef {Object} MessageDescriptor
* @property {string} nodeType The type of node.
* @property {Location} loc The location of the problem.
* @property {string} message The problem message.
* @property {Object} [data] Optional data to use to fill in placeholders in the
* message.
* @property {Function} fix The function to call that creates a fix command.
*/
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/**
* Acts as an abstraction layer between rules and the main eslint object.
* @constructor
* @param {string} ruleId The ID of the rule using this object.
* @param {eslint} eslint The eslint object.
* @param {number} severity The configured severity level of the rule.
* @param {array} options The configuration information to be added to the rule.
* @param {object} settings The configuration settings passed from the config file.
* @param {object} ecmaFeatures The ecmaFeatures settings passed from the config file.
*/
function RuleContext(ruleId, eslint, severity, options, settings, ecmaFeatures) {
/**
* The read-only ID of the rule.
*/
Object.defineProperty(this, "id", {
value: ruleId
});
/**
* The read-only options of the rule
*/
Object.defineProperty(this, "options", {
value: options
});
/**
* The read-only settings shared between all rules
*/
Object.defineProperty(this, "settings", {
value: settings
});
/**
* The read-only ecmaFeatures shared across all rules
*/
Object.defineProperty(this, "ecmaFeatures", {
value: Object.create(ecmaFeatures)
});
Object.freeze(this.ecmaFeatures);
// copy over passthrough methods
PASSTHROUGHS.forEach(function(name) {
this[name] = function() {
return eslint[name].apply(eslint, arguments);
};
}, this);
/**
* Passthrough to eslint.report() that automatically assigns the rule ID and severity.
* @param {ASTNode|MessageDescriptor} nodeOrDescriptor The AST node related to the message or a message
* descriptor.
* @param {Object=} location The location of the error.
* @param {string} message The message to display to the user.
* @param {Object} opts Optional template data which produces a formatted message
* with symbols being replaced by this object's values.
* @returns {void}
*/
this.report = function(nodeOrDescriptor, location, message, opts) {
var descriptor,
fix = null;
// check to see if it's a new style call
if (arguments.length === 1) {
descriptor = nodeOrDescriptor;
// if there's a fix specified, get it
if (typeof descriptor.fix === "function") {
fix = descriptor.fix(new RuleFixer());
}
eslint.report(
ruleId, severity, descriptor.node,
descriptor.loc || descriptor.node.loc.start,
descriptor.message, descriptor.data, fix
);
return;
}
// old style call
eslint.report(ruleId, severity, nodeOrDescriptor, location, message, opts);
};
/**
* Passthrough to eslint.getSourceCode().
* @returns {SourceCode} The SourceCode object for the code.
*/
this.getSourceCode = function() {
return eslint.getSourceCode();
};
}
RuleContext.prototype = {
constructor: RuleContext
};
module.exports = RuleContext;

96
node_modules/eslint/lib/rules.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
/**
* @fileoverview Defines a storage for rules.
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var loadRules = require("./load-rules");
//------------------------------------------------------------------------------
// Privates
//------------------------------------------------------------------------------
var rules = Object.create(null);
//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
/**
* Registers a rule module for rule id in storage.
* @param {String} ruleId Rule id (file name).
* @param {Function} ruleModule Rule handler.
* @returns {void}
*/
function define(ruleId, ruleModule) {
rules[ruleId] = ruleModule;
}
/**
* Loads and registers all rules from passed rules directory.
* @param {String} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`.
* @returns {void}
*/
function load(rulesDir) {
var newRules = loadRules(rulesDir);
Object.keys(newRules).forEach(function(ruleId) {
define(ruleId, newRules[ruleId]);
});
}
/**
* Registers all given rules of a plugin.
* @param {Object} pluginRules A key/value map of rule definitions.
* @param {String} pluginName The name of the plugin without prefix (`eslint-plugin-`).
* @returns {void}
*/
function importPlugin(pluginRules, pluginName) {
Object.keys(pluginRules).forEach(function(ruleId) {
var qualifiedRuleId = pluginName + "/" + ruleId,
rule = pluginRules[ruleId];
define(qualifiedRuleId, rule);
});
}
/**
* Access rule handler by id (file name).
* @param {String} ruleId Rule id (file name).
* @returns {Function} Rule handler.
*/
function get(ruleId) {
if (typeof rules[ruleId] === "string") {
return require(rules[ruleId]);
} else {
return rules[ruleId];
}
}
/**
* Reset rules storage.
* Should be used only in tests.
* @returns {void}
*/
function testClear() {
rules = Object.create(null);
}
module.exports = {
define: define,
load: load,
import: importPlugin,
get: get,
testClear: testClear
};
//------------------------------------------------------------------------------
// Initialization
//------------------------------------------------------------------------------
// loads built-in rules
load();

145
node_modules/eslint/lib/rules/accessor-pairs.js generated vendored Normal file
View File

@@ -0,0 +1,145 @@
/**
* @fileoverview Rule to flag wrapping non-iife in parens
* @author Gyandeep Singh
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether or not a given node is an `Identifier` node which was named a given name.
* @param {ASTNode} node - A node to check.
* @param {string} name - An expected name of the node.
* @returns {boolean} `true` if the node is an `Identifier` node which was named as expected.
*/
function isIdentifier(node, name) {
return node.type === "Identifier" && node.name === name;
}
/**
* Checks whether or not a given node is an argument of a specified method call.
* @param {ASTNode} node - A node to check.
* @param {number} index - An expected index of the node in arguments.
* @param {string} object - An expected name of the object of the method.
* @param {string} property - An expected name of the method.
* @returns {boolean} `true` if the node is an argument of the specified method call.
*/
function isArgumentOfMethodCall(node, index, object, property) {
var parent = node.parent;
return (
parent.type === "CallExpression" &&
parent.callee.type === "MemberExpression" &&
parent.callee.computed === false &&
isIdentifier(parent.callee.object, object) &&
isIdentifier(parent.callee.property, property) &&
parent.arguments[index] === node
);
}
/**
* Checks whether or not a given node is a property descriptor.
* @param {ASTNode} node - A node to check.
* @returns {boolean} `true` if the node is a property descriptor.
*/
function isPropertyDescriptor(node) {
// Object.defineProperty(obj, "foo", {set: ...})
if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") ||
isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty")
) {
return true;
}
// Object.defineProperties(obj, {foo: {set: ...}})
// Object.create(proto, {foo: {set: ...}})
node = node.parent.parent;
return node.type === "ObjectExpression" && (
isArgumentOfMethodCall(node, 1, "Object", "create") ||
isArgumentOfMethodCall(node, 1, "Object", "defineProperties")
);
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var config = context.options[0] || {};
var checkGetWithoutSet = config.getWithoutSet === true;
var checkSetWithoutGet = config.setWithoutGet !== false;
/**
* Checks a object expression to see if it has setter and getter both present or none.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkLonelySetGet(node) {
var isSetPresent = false;
var isGetPresent = false;
var isDescriptor = isPropertyDescriptor(node);
for (var i = 0, end = node.properties.length; i < end; i++) {
var property = node.properties[i];
var propToCheck = "";
if (property.kind === "init") {
if (isDescriptor && !property.computed) {
propToCheck = property.key.name;
}
} else {
propToCheck = property.kind;
}
switch (propToCheck) {
case "set":
isSetPresent = true;
break;
case "get":
isGetPresent = true;
break;
default:
// Do nothing
}
if (isSetPresent && isGetPresent) {
break;
}
}
if (checkSetWithoutGet && isSetPresent && !isGetPresent) {
context.report(node, "Getter is not present");
} else if (checkGetWithoutSet && isGetPresent && !isSetPresent) {
context.report(node, "Setter is not present");
}
}
return {
"ObjectExpression": function(node) {
if (checkSetWithoutGet || checkGetWithoutSet) {
checkLonelySetGet(node);
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"getWithoutSet": {
"type": "boolean"
},
"setWithoutGet": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

209
node_modules/eslint/lib/rules/array-bracket-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,209 @@
/**
* @fileoverview Disallows or enforces spaces inside of array brackets.
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
* @copyright 2014 Brandyn Bennett. All rights reserved.
* @copyright 2014 Michael Ficarra. No rights reserved.
* @copyright 2014 Vignesh Anand. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var spaced = context.options[0] === "always",
sourceCode = context.getSourceCode();
/**
* Determines whether an option is set, relative to the spacing option.
* If spaced is "always", then check whether option is set to false.
* If spaced is "never", then check whether option is set to true.
* @param {Object} option - The option to exclude.
* @returns {boolean} Whether or not the property is excluded.
*/
function isOptionSet(option) {
return context.options[1] ? context.options[1][option] === !spaced : false;
}
var options = {
spaced: spaced,
singleElementException: isOptionSet("singleValue"),
objectsInArraysException: isOptionSet("objectsInArrays"),
arraysInArraysException: isOptionSet("arraysInArrays")
};
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Reports that there shouldn't be a space after the first token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportNoBeginningSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "There should be no space after '" + token.value + "'",
fix: function(fixer) {
var nextToken = context.getSourceCode().getTokenAfter(token);
return fixer.removeRange([token.range[1], nextToken.range[0]]);
}
});
}
/**
* Reports that there shouldn't be a space before the last token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportNoEndingSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "There should be no space before '" + token.value + "'",
fix: function(fixer) {
var previousToken = context.getSourceCode().getTokenBefore(token);
return fixer.removeRange([previousToken.range[1], token.range[0]]);
}
});
}
/**
* Reports that there should be a space after the first token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportRequiredBeginningSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "A space is required after '" + token.value + "'",
fix: function(fixer) {
return fixer.insertTextAfter(token, " ");
}
});
}
/**
* Reports that there should be a space before the last token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportRequiredEndingSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "A space is required before '" + token.value + "'",
fix: function(fixer) {
return fixer.insertTextBefore(token, " ");
}
});
}
/**
* Determines if a node is an object type
* @param {ASTNode} node - The node to check.
* @returns {boolean} Whether or not the node is an object type.
*/
function isObjectType(node) {
return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern");
}
/**
* Determines if a node is an array type
* @param {ASTNode} node - The node to check.
* @returns {boolean} Whether or not the node is an array type.
*/
function isArrayType(node) {
return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern");
}
/**
* Validates the spacing around array brackets
* @param {ASTNode} node - The node we're checking for spacing
* @returns {void}
*/
function validateArraySpacing(node) {
if (options.spaced && node.elements.length === 0) {
return;
}
var first = context.getFirstToken(node),
second = context.getFirstToken(node, 1),
penultimate = context.getLastToken(node, 1),
last = context.getLastToken(node),
firstElement = node.elements[0],
lastElement = node.elements[node.elements.length - 1];
var openingBracketMustBeSpaced =
options.objectsInArraysException && isObjectType(firstElement) ||
options.arraysInArraysException && isArrayType(firstElement) ||
options.singleElementException && node.elements.length === 1
? !options.spaced : options.spaced;
var closingBracketMustBeSpaced =
options.objectsInArraysException && isObjectType(lastElement) ||
options.arraysInArraysException && isArrayType(lastElement) ||
options.singleElementException && node.elements.length === 1
? !options.spaced : options.spaced;
if (astUtils.isTokenOnSameLine(first, second)) {
if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) {
reportRequiredBeginningSpace(node, first);
}
if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) {
reportNoBeginningSpace(node, first);
}
}
if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) {
if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) {
reportRequiredEndingSpace(node, last);
}
if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) {
reportNoEndingSpace(node, last);
}
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
ArrayPattern: validateArraySpacing,
ArrayExpression: validateArraySpacing
};
};
module.exports.schema = [
{
"enum": ["always", "never"]
},
{
"type": "object",
"properties": {
"singleValue": {
"type": "boolean"
},
"objectsInArrays": {
"type": "boolean"
},
"arraysInArrays": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

71
node_modules/eslint/lib/rules/arrow-body-style.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
/**
* @fileoverview Rule to require braces in arrow function body.
* @author Alberto Rodríguez
* @copyright 2015 Alberto Rodríguez. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var always = context.options[0] === "always";
var asNeeded = !context.options[0] || context.options[0] === "as-needed";
/**
* Determines whether a arrow function body needs braces
* @param {ASTNode} node The arrow function node.
* @returns {void}
*/
function validate(node) {
var arrowBody = node.body;
if (arrowBody.type === "BlockStatement") {
var blockBody = arrowBody.body;
if (blockBody.length > 1) {
return;
}
if (blockBody.length === 0) {
var hasComments = context.getComments(arrowBody).trailing.length > 0;
if (hasComments) {
return;
}
context.report({
node: node,
loc: arrowBody.loc.start,
message: "Unexpected empty block in arrow body."
});
} else {
if (asNeeded && blockBody[0].type === "ReturnStatement") {
context.report({
node: node,
loc: arrowBody.loc.start,
message: "Unexpected block statement surrounding arrow body."
});
}
}
} else {
if (always) {
context.report({
node: node,
loc: arrowBody.loc.start,
message: "Expected block statement surrounding arrow body."
});
}
}
}
return {
"ArrowFunctionExpression": validate
};
};
module.exports.schema = [
{
"enum": ["always", "as-needed"]
}
];

52
node_modules/eslint/lib/rules/arrow-parens.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
/**
* @fileoverview Rule to require parens in arrow function arguments.
* @author Jxck
* @copyright 2015 Jxck. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var message = "Expected parentheses around arrow function argument.";
var asNeededMessage = "Unexpected parentheses around single function argument";
var asNeeded = context.options[0] === "as-needed";
/**
* Determines whether a arrow function argument end with `)`
* @param {ASTNode} node The arrow function node.
* @returns {void}
*/
function parens(node) {
var token = context.getFirstToken(node);
// as-needed: x => x
if (asNeeded && node.params.length === 1 && node.params[0].type === "Identifier") {
if (token.type === "Punctuator" && token.value === "(") {
context.report(node, asNeededMessage);
}
return;
}
if (token.type === "Identifier") {
var after = context.getTokenAfter(token);
// (x) => x
if (after.value !== ")") {
context.report(node, message);
}
}
}
return {
"ArrowFunctionExpression": parens
};
};
module.exports.schema = [
{
"enum": ["always", "as-needed"]
}
];

124
node_modules/eslint/lib/rules/arrow-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,124 @@
/**
* @fileoverview Rule to require parens in arrow function arguments.
* @author Jxck
* @copyright 2015 Jxck. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
// merge rules with default
var rule = { before: true, after: true };
var option = context.options[0] || {};
rule.before = option.before !== false;
rule.after = option.after !== false;
/**
* Get tokens of arrow(`=>`) and before/after arrow.
* @param {ASTNode} node The arrow function node.
* @returns {Object} Tokens of arrow and before/after arrow.
*/
function getTokens(node) {
var t = context.getFirstToken(node);
var before;
while (t.type !== "Punctuator" || t.value !== "=>") {
before = t;
t = context.getTokenAfter(t);
}
var after = context.getTokenAfter(t);
return { before: before, arrow: t, after: after };
}
/**
* Count spaces before/after arrow(`=>`) token.
* @param {Object} tokens Tokens before/after arrow.
* @returns {Object} count of space before/after arrow.
*/
function countSpaces(tokens) {
var before = tokens.arrow.range[0] - tokens.before.range[1];
var after = tokens.after.range[0] - tokens.arrow.range[1];
return { before: before, after: after };
}
/**
* Determines whether space(s) before after arrow(`=>`) is satisfy rule.
* if before/after value is `true`, there should be space(s).
* if before/after value is `false`, there should be no space.
* @param {ASTNode} node The arrow function node.
* @returns {void}
*/
function spaces(node) {
var tokens = getTokens(node);
var countSpace = countSpaces(tokens);
if (rule.before) {
// should be space(s) before arrow
if (countSpace.before === 0) {
context.report({
node: tokens.before,
message: "Missing space before =>",
fix: function(fixer) {
return fixer.insertTextBefore(tokens.arrow, " ");
}
});
}
} else {
// should be no space before arrow
if (countSpace.before > 0) {
context.report({
node: tokens.before,
message: "Unexpected space before =>",
fix: function(fixer) {
return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]);
}
});
}
}
if (rule.after) {
// should be space(s) after arrow
if (countSpace.after === 0) {
context.report({
node: tokens.after,
message: "Missing space after =>",
fix: function(fixer) {
return fixer.insertTextAfter(tokens.arrow, " ");
}
});
}
} else {
// should be no space after arrow
if (countSpace.after > 0) {
context.report({
node: tokens.after,
message: "Unexpected space after =>",
fix: function(fixer) {
return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]);
}
});
}
}
}
return {
"ArrowFunctionExpression": spaces
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"before": {
"type": "boolean"
},
"after": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

142
node_modules/eslint/lib/rules/block-scoped-var.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
/**
* @fileoverview Rule to check for "block scoped" variables by binding context
* @author Matt DuVall <http://www.mattduvall.com>
* @copyright 2015 Toru Nagashima. All rights reserved.
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Collects unresolved references from the global scope, then creates a map to references from its name.
* @param {RuleContext} context - The current context.
* @returns {object} A map object. Its key is the variable names. Its value is the references of each variable.
*/
function collectUnresolvedReferences(context) {
var unresolved = Object.create(null);
var references = context.getScope().through;
for (var i = 0; i < references.length; ++i) {
var reference = references[i];
var name = reference.identifier.name;
if (name in unresolved === false) {
unresolved[name] = [];
}
unresolved[name].push(reference);
}
return unresolved;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var unresolvedReferences = Object.create(null);
var stack = [];
/**
* Makes a block scope.
* @param {ASTNode} node - A node of a scope.
* @returns {void}
*/
function enterScope(node) {
stack.push(node.range);
}
/**
* Pops the last block scope.
* @returns {void}
*/
function exitScope() {
stack.pop();
}
/**
* Reports a given reference.
* @param {escope.Reference} reference - A reference to report.
* @returns {void}
*/
function report(reference) {
var identifier = reference.identifier;
context.report(
identifier,
"\"{{name}}\" used outside of binding context.",
{name: identifier.name});
}
/**
* Finds and reports references which are outside of valid scopes.
* @param {ASTNode} node - A node to get variables.
* @returns {void}
*/
function checkForVariables(node) {
if (node.kind !== "var") {
return;
}
var isGlobal = context.getScope().type === "global";
// Defines a predicate to check whether or not a given reference is outside of valid scope.
var scopeRange = stack[stack.length - 1];
/**
* Check if a reference is out of scope
* @param {ASTNode} reference node to examine
* @returns {boolean} True is its outside the scope
* @private
*/
function isOutsideOfScope(reference) {
var idRange = reference.identifier.range;
return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1];
}
// Gets declared variables, and checks its references.
var variables = context.getDeclaredVariables(node);
for (var i = 0; i < variables.length; ++i) {
var variable = variables[i];
var references = variable.references;
// Global variables are not resolved.
// In this case, use unresolved references.
if (isGlobal && variable.name in unresolvedReferences) {
references = unresolvedReferences[variable.name];
}
// Reports.
references.filter(isOutsideOfScope).forEach(report);
}
}
return {
"Program": function(node) {
unresolvedReferences = collectUnresolvedReferences(context);
stack = [node.range];
},
// Manages scopes.
"BlockStatement": enterScope,
"BlockStatement:exit": exitScope,
"ForStatement": enterScope,
"ForStatement:exit": exitScope,
"ForInStatement": enterScope,
"ForInStatement:exit": exitScope,
"ForOfStatement": enterScope,
"ForOfStatement:exit": exitScope,
"SwitchStatement": enterScope,
"SwitchStatement:exit": exitScope,
"CatchClause": enterScope,
"CatchClause:exit": exitScope,
// Finds and reports references which are outside of valid scope.
"VariableDeclaration": checkForVariables
};
};
module.exports.schema = [];

119
node_modules/eslint/lib/rules/block-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,119 @@
/**
* @fileoverview A rule to disallow or enforce spaces inside of single line blocks.
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/
"use strict";
var util = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var always = (context.options[0] !== "never"),
message = always ? "Requires a space" : "Unexpected space(s)",
sourceCode = context.getSourceCode();
/**
* Gets the open brace token from a given node.
* @param {ASTNode} node - A BlockStatement/SwitchStatement node to get.
* @returns {Token} The token of the open brace.
*/
function getOpenBrace(node) {
if (node.type === "SwitchStatement") {
if (node.cases.length > 0) {
return context.getTokenBefore(node.cases[0]);
}
return context.getLastToken(node, 1);
}
return context.getFirstToken(node);
}
/**
* Checks whether or not:
* - given tokens are on same line.
* - there is/isn't a space between given tokens.
* @param {Token} left - A token to check.
* @param {Token} right - The token which is next to `left`.
* @returns {boolean}
* When the option is `"always"`, `true` if there are one or more spaces between given tokens.
* When the option is `"never"`, `true` if there are not any spaces between given tokens.
* If given tokens are not on same line, it's always `true`.
*/
function isValid(left, right) {
return (
!util.isTokenOnSameLine(left, right) ||
sourceCode.isSpaceBetweenTokens(left, right) === always
);
}
/**
* Reports invalid spacing style inside braces.
* @param {ASTNode} node - A BlockStatement/SwitchStatement node to get.
* @returns {void}
*/
function checkSpacingInsideBraces(node) {
// Gets braces and the first/last token of content.
var openBrace = getOpenBrace(node);
var closeBrace = context.getLastToken(node);
var firstToken = sourceCode.getTokenOrCommentAfter(openBrace);
var lastToken = sourceCode.getTokenOrCommentBefore(closeBrace);
// Skip if the node is invalid or empty.
if (openBrace.type !== "Punctuator" ||
openBrace.value !== "{" ||
closeBrace.type !== "Punctuator" ||
closeBrace.value !== "}" ||
firstToken === closeBrace
) {
return;
}
// Skip line comments for option never
if (!always && firstToken.type === "Line") {
return;
}
// Check.
if (!isValid(openBrace, firstToken)) {
context.report({
node: node,
loc: openBrace.loc.start,
message: message + " after \"{\".",
fix: function(fixer) {
if (always) {
return fixer.insertTextBefore(firstToken, " ");
}
return fixer.removeRange([openBrace.range[1], firstToken.range[0]]);
}
});
}
if (!isValid(lastToken, closeBrace)) {
context.report({
node: node,
loc: closeBrace.loc.start,
message: message + " before \"}\".",
fix: function(fixer) {
if (always) {
return fixer.insertTextAfter(lastToken, " ");
}
return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]);
}
});
}
}
return {
BlockStatement: checkSpacingInsideBraces,
SwitchStatement: checkSpacingInsideBraces
};
};
module.exports.schema = [
{enum: ["always", "never"]}
];

229
node_modules/eslint/lib/rules/brace-style.js generated vendored Normal file
View File

@@ -0,0 +1,229 @@
/**
* @fileoverview Rule to flag block statements that do not use the one true brace style
* @author Ian Christian Myers
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var style = context.options[0] || "1tbs";
var params = context.options[1] || {};
var OPEN_MESSAGE = "Opening curly brace does not appear on the same line as controlling statement.",
OPEN_MESSAGE_ALLMAN = "Opening curly brace appears on the same line as controlling statement.",
BODY_MESSAGE = "Statement inside of curly braces should be on next line.",
CLOSE_MESSAGE = "Closing curly brace does not appear on the same line as the subsequent block.",
CLOSE_MESSAGE_SINGLE = "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
CLOSE_MESSAGE_STROUSTRUP_ALLMAN = "Closing curly brace appears on the same line as the subsequent block.";
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Determines if a given node is a block statement.
* @param {ASTNode} node The node to check.
* @returns {boolean} True if the node is a block statement, false if not.
* @private
*/
function isBlock(node) {
return node && node.type === "BlockStatement";
}
/**
* Check if the token is an punctuator with a value of curly brace
* @param {object} token - Token to check
* @returns {boolean} true if its a curly punctuator
* @private
*/
function isCurlyPunctuator(token) {
return token.value === "{" || token.value === "}";
}
/**
* Binds a list of properties to a function that verifies that the opening
* curly brace is on the same line as its controlling statement of a given
* node.
* @param {...string} The properties to check on the node.
* @returns {Function} A function that will perform the check on a node
* @private
*/
function checkBlock() {
var blockProperties = arguments;
return function(node) {
[].forEach.call(blockProperties, function(blockProp) {
var block = node[blockProp], previousToken, curlyToken, curlyTokenEnd, curlyTokensOnSameLine;
if (!isBlock(block)) {
return;
}
previousToken = context.getTokenBefore(block);
curlyToken = context.getFirstToken(block);
curlyTokenEnd = context.getLastToken(block);
curlyTokensOnSameLine = curlyToken.loc.start.line === curlyTokenEnd.loc.start.line;
if (style !== "allman" && previousToken.loc.start.line !== curlyToken.loc.start.line) {
context.report(node, OPEN_MESSAGE);
} else if (style === "allman" && previousToken.loc.start.line === curlyToken.loc.start.line && !params.allowSingleLine) {
context.report(node, OPEN_MESSAGE_ALLMAN);
}
if (!block.body.length || curlyTokensOnSameLine && params.allowSingleLine) {
return;
}
if (curlyToken.loc.start.line === block.body[0].loc.start.line) {
context.report(block.body[0], BODY_MESSAGE);
} else if (curlyTokenEnd.loc.start.line === block.body[block.body.length - 1].loc.start.line) {
context.report(block.body[block.body.length - 1], CLOSE_MESSAGE_SINGLE);
}
});
};
}
/**
* Enforces the configured brace style on IfStatements
* @param {ASTNode} node An IfStatement node.
* @returns {void}
* @private
*/
function checkIfStatement(node) {
var tokens,
alternateIsBlock = false,
alternateIsIfBlock = false;
checkBlock("consequent", "alternate")(node);
if (node.alternate) {
alternateIsBlock = isBlock(node.alternate);
alternateIsIfBlock = node.alternate.type === "IfStatement" && isBlock(node.alternate.consequent);
if (alternateIsBlock || alternateIsIfBlock) {
tokens = context.getTokensBefore(node.alternate, 2);
if (style === "1tbs") {
if (tokens[0].loc.start.line !== tokens[1].loc.start.line &&
node.consequent.type === "BlockStatement" &&
isCurlyPunctuator(tokens[0]) ) {
context.report(node.alternate, CLOSE_MESSAGE);
}
} else if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
context.report(node.alternate, CLOSE_MESSAGE_STROUSTRUP_ALLMAN);
}
}
}
}
/**
* Enforces the configured brace style on TryStatements
* @param {ASTNode} node A TryStatement node.
* @returns {void}
* @private
*/
function checkTryStatement(node) {
var tokens;
checkBlock("block", "finalizer")(node);
if (isBlock(node.finalizer)) {
tokens = context.getTokensBefore(node.finalizer, 2);
if (style === "1tbs") {
if (tokens[0].loc.start.line !== tokens[1].loc.start.line) {
context.report(node.finalizer, CLOSE_MESSAGE);
}
} else if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
context.report(node.finalizer, CLOSE_MESSAGE_STROUSTRUP_ALLMAN);
}
}
}
/**
* Enforces the configured brace style on CatchClauses
* @param {ASTNode} node A CatchClause node.
* @returns {void}
* @private
*/
function checkCatchClause(node) {
var previousToken = context.getTokenBefore(node),
firstToken = context.getFirstToken(node);
checkBlock("body")(node);
if (isBlock(node.body)) {
if (style === "1tbs") {
if (previousToken.loc.start.line !== firstToken.loc.start.line) {
context.report(node, CLOSE_MESSAGE);
}
} else {
if (previousToken.loc.start.line === firstToken.loc.start.line) {
context.report(node, CLOSE_MESSAGE_STROUSTRUP_ALLMAN);
}
}
}
}
/**
* Enforces the configured brace style on SwitchStatements
* @param {ASTNode} node A SwitchStatement node.
* @returns {void}
* @private
*/
function checkSwitchStatement(node) {
var tokens;
if (node.cases && node.cases.length) {
tokens = context.getTokensBefore(node.cases[0], 2);
} else {
tokens = context.getLastTokens(node, 3);
}
if (style !== "allman" && tokens[0].loc.start.line !== tokens[1].loc.start.line) {
context.report(node, OPEN_MESSAGE);
} else if (style === "allman" && tokens[0].loc.start.line === tokens[1].loc.start.line) {
context.report(node, OPEN_MESSAGE_ALLMAN);
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"FunctionDeclaration": checkBlock("body"),
"FunctionExpression": checkBlock("body"),
"ArrowFunctionExpression": checkBlock("body"),
"IfStatement": checkIfStatement,
"TryStatement": checkTryStatement,
"CatchClause": checkCatchClause,
"DoWhileStatement": checkBlock("body"),
"WhileStatement": checkBlock("body"),
"WithStatement": checkBlock("body"),
"ForStatement": checkBlock("body"),
"ForInStatement": checkBlock("body"),
"ForOfStatement": checkBlock("body"),
"SwitchStatement": checkSwitchStatement
};
};
module.exports.schema = [
{
"enum": ["1tbs", "stroustrup", "allman"]
},
{
"type": "object",
"properties": {
"allowSingleLine": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

142
node_modules/eslint/lib/rules/callback-return.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
/**
* @fileoverview Enforce return after a callback.
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var callbacks = context.options[0] || ["callback", "cb", "next"];
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Find the closest parent matching a list of types.
* @param {ASTNode} node The node whose parents we are searching
* @param {Array} types The node types to match
* @returns {ASTNode} The matched node or undefined.
*/
function findClosestParentOfType(node, types) {
if (!node.parent) {
return null;
}
if (types.indexOf(node.parent.type) === -1) {
return findClosestParentOfType(node.parent, types);
}
return node.parent;
}
/**
* Check to see if a CallExpression is in our callback list.
* @param {ASTNode} node The node to check against our callback names list.
* @returns {Boolean} Whether or not this function matches our callback name.
*/
function isCallback(node) {
return node.callee.type === "Identifier" && callbacks.indexOf(node.callee.name) > -1;
}
/**
* Determines whether or not the callback is part of a callback expression.
* @param {ASTNode} node The callback node
* @param {ASTNode} parentNode The expression node
* @returns {boolean} Whether or not this is part of a callback expression
*/
function isCallbackExpression(node, parentNode) {
// ensure the parent node exists and is an expression
if (!parentNode || parentNode.type !== "ExpressionStatement") {
return false;
}
// cb()
if (parentNode.expression === node) {
return true;
}
// special case for cb && cb() and similar
if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") {
if (parentNode.expression.right === node) {
return true;
}
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"CallExpression": function(node) {
// if we"re not a callback we can return
if (!isCallback(node)) {
return;
}
// find the closest block, return or loop
var closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {},
lastItem, parentType;
// if our parent is a return we know we're ok
if (closestBlock.type === "ReturnStatement" ) {
return;
}
// arrow functions don't always have blocks and implicitly return
if (closestBlock.type === "ArrowFunctionExpression") {
return;
}
// block statements are part of functions and most if statements
if (closestBlock.type === "BlockStatement") {
// find the last item in the block
lastItem = closestBlock.body[closestBlock.body.length - 1];
// if the callback is the last thing in a block that might be ok
if (isCallbackExpression(node, lastItem)) {
parentType = closestBlock.parent.type;
// but only if the block is part of a function
if (parentType === "FunctionExpression" ||
parentType === "FunctionDeclaration" ||
parentType === "ArrowFunctionExpression"
) {
return;
}
}
// ending a block with a return is also ok
if (lastItem.type === "ReturnStatement") {
// but only if the callback is immediately before
if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) {
return;
}
}
}
// as long as you're the child of a function at this point you should be asked to return
if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) {
context.report(node, "Expected return with your callback function.");
}
}
};
};
module.exports.schema = [{
type: "array",
items: { type: "string" }
}];

111
node_modules/eslint/lib/rules/camelcase.js generated vendored Normal file
View File

@@ -0,0 +1,111 @@
/**
* @fileoverview Rule to flag non-camelcased identifiers
* @author Nicholas C. Zakas
* @copyright 2015 Dieter Oberkofler. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Checks if a string contains an underscore and isn't all upper-case
* @param {String} name The string to check.
* @returns {boolean} if the string is underscored
* @private
*/
function isUnderscored(name) {
// if there's an underscore, it might be A_CONSTANT, which is okay
return name.indexOf("_") > -1 && name !== name.toUpperCase();
}
/**
* Reports an AST node as a rule violation.
* @param {ASTNode} node The node to report.
* @returns {void}
* @private
*/
function report(node) {
context.report(node, "Identifier '{{name}}' is not in camel case.", { name: node.name });
}
var options = context.options[0] || {},
properties = options.properties || "";
if (properties !== "always" && properties !== "never") {
properties = "always";
}
return {
"Identifier": function(node) {
// Leading and trailing underscores are commonly used to flag private/protected identifiers, strip them
var name = node.name.replace(/^_+|_+$/g, ""),
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
// MemberExpressions get special rules
if (node.parent.type === "MemberExpression") {
// "never" check properties
if (properties === "never") {
return;
}
// Always report underscored object names
if (node.parent.object.type === "Identifier" &&
node.parent.object.name === node.name &&
isUnderscored(name)) {
report(node);
// Report AssignmentExpressions only if they are the left side of the assignment
} else if (effectiveParent.type === "AssignmentExpression" &&
isUnderscored(name) &&
(effectiveParent.right.type !== "MemberExpression" ||
effectiveParent.left.type === "MemberExpression" &&
effectiveParent.left.property.name === node.name)) {
report(node);
}
// Properties have their own rules
} else if (node.parent.type === "Property") {
// "never" check properties
if (properties === "never") {
return;
}
if (isUnderscored(name) && effectiveParent.type !== "CallExpression") {
report(node);
}
// Report anything that is underscored that isn't a CallExpression
} else if (isUnderscored(name) && effectiveParent.type !== "CallExpression") {
report(node);
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"properties": {
"enum": ["always", "never"]
}
},
"additionalProperties": false
}
];

208
node_modules/eslint/lib/rules/comma-dangle.js generated vendored Normal file
View File

@@ -0,0 +1,208 @@
/**
* @fileoverview Rule to forbid or enforce dangling commas.
* @author Ian Christian Myers
* @copyright 2015 Toru Nagashima
* @copyright 2015 Mathias Schreck
* @copyright 2013 Ian Christian Myers
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Gets the last element of a given array.
*
* @param {*[]} xs - An array to get.
* @returns {*} The last element, or undefined.
*/
function getLast(xs) {
if (xs.length === 0) {
return null;
}
return xs[xs.length - 1];
}
/**
* Checks whether or not a trailing comma is allowed in a given node.
* `ArrayPattern` which has `RestElement` disallows it.
*
* @param {ASTNode} node - A node to check.
* @param {ASTNode} lastItem - The node of the last element in the given node.
* @returns {boolean} `true` if a trailing comma is allowed.
*/
function isTrailingCommaAllowed(node, lastItem) {
switch (node.type) {
case "ArrayPattern":
// TODO(t-nagashima): Remove SpreadElement after https://github.com/eslint/espree/issues/194 was fixed.
return (
lastItem.type !== "RestElement" &&
lastItem.type !== "SpreadElement"
);
// TODO(t-nagashima): Remove this case after https://github.com/eslint/espree/issues/195 was fixed.
case "ArrayExpression":
return (
node.parent.type !== "ForOfStatement" ||
node.parent.left !== node ||
lastItem.type !== "SpreadElement"
);
default:
return true;
}
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var mode = context.options[0];
var UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
var MISSING_MESSAGE = "Missing trailing comma.";
/**
* Checks whether or not a given node is multiline.
* This rule handles a given node as multiline when the closing parenthesis
* and the last element are not on the same line.
*
* @param {ASTNode} node - A ndoe to check.
* @returns {boolean} `true` if the node is multiline.
*/
function isMultiline(node) {
var lastItem = getLast(node.properties || node.elements || node.specifiers);
if (!lastItem) {
return false;
}
var sourceCode = context.getSourceCode(),
penultimateToken = sourceCode.getLastToken(lastItem),
lastToken = sourceCode.getLastToken(node);
if (lastToken.value === ",") {
penultimateToken = lastToken;
lastToken = sourceCode.getTokenAfter(lastToken);
}
return lastToken.loc.end.line !== penultimateToken.loc.end.line;
}
/**
* Reports a trailing comma if it exists.
*
* @param {ASTNode} node - A node to check. Its type is one of
* ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
* ImportDeclaration, and ExportNamedDeclaration.
* @returns {void}
*/
function forbidTrailingComma(node) {
var lastItem = getLast(node.properties || node.elements || node.specifiers);
if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
return;
}
var sourceCode = context.getSourceCode(),
trailingToken;
// last item can be surrounded by parentheses for object and array literals
if (node.type === "ObjectExpression" || node.type === "ArrayExpression") {
trailingToken = sourceCode.getTokenBefore(sourceCode.getLastToken(node));
} else {
trailingToken = sourceCode.getTokenAfter(lastItem);
}
if (trailingToken.value === ",") {
context.report(
lastItem,
trailingToken.loc.start,
UNEXPECTED_MESSAGE);
}
}
/**
* Reports the last element of a given node if it does not have a trailing
* comma.
*
* If a given node is `ArrayPattern` which has `RestElement`, the trailing
* comma is disallowed, so report if it exists.
*
* @param {ASTNode} node - A node to check. Its type is one of
* ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
* ImportDeclaration, and ExportNamedDeclaration.
* @returns {void}
*/
function forceTrailingComma(node) {
var lastItem = getLast(node.properties || node.elements || node.specifiers);
if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) {
return;
}
if (!isTrailingCommaAllowed(node, lastItem)) {
forbidTrailingComma(node);
return;
}
var sourceCode = context.getSourceCode(),
trailingToken;
// last item can be surrounded by parentheses for object and array literals
if (node.type === "ObjectExpression" || node.type === "ArrayExpression") {
trailingToken = sourceCode.getTokenBefore(sourceCode.getLastToken(node));
} else {
trailingToken = sourceCode.getTokenAfter(lastItem);
}
if (trailingToken.value !== ",") {
context.report(
lastItem,
lastItem.loc.end,
MISSING_MESSAGE);
}
}
/**
* If a given node is multiline, reports the last element of a given node
* when it does not have a trailing comma.
* Otherwise, reports a trailing comma if it exists.
*
* @param {ASTNode} node - A node to check. Its type is one of
* ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern,
* ImportDeclaration, and ExportNamedDeclaration.
* @returns {void}
*/
function forceTrailingCommaIfMultiline(node) {
if (isMultiline(node)) {
forceTrailingComma(node);
} else {
forbidTrailingComma(node);
}
}
// Chooses a checking function.
var checkForTrailingComma;
if (mode === "always") {
checkForTrailingComma = forceTrailingComma;
} else if (mode === "always-multiline") {
checkForTrailingComma = forceTrailingCommaIfMultiline;
} else {
checkForTrailingComma = forbidTrailingComma;
}
return {
"ObjectExpression": checkForTrailingComma,
"ObjectPattern": checkForTrailingComma,
"ArrayExpression": checkForTrailingComma,
"ArrayPattern": checkForTrailingComma,
"ImportDeclaration": checkForTrailingComma,
"ExportNamedDeclaration": checkForTrailingComma
};
};
module.exports.schema = [
{
"enum": ["always", "always-multiline", "never"]
}
];

183
node_modules/eslint/lib/rules/comma-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,183 @@
/**
* @fileoverview Comma spacing - validates spacing before and after comma
* @author Vignesh Anand aka vegetableman.
* @copyright 2014 Vignesh Anand. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var sourceCode = context.getSourceCode();
var tokensAndComments = sourceCode.tokensAndComments;
var options = {
before: context.options[0] ? !!context.options[0].before : false,
after: context.options[0] ? !!context.options[0].after : true
};
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
// list of comma tokens to ignore for the check of leading whitespace
var commaTokensToIgnore = [];
/**
* Determines if a given token is a comma operator.
* @param {ASTNode} token The token to check.
* @returns {boolean} True if the token is a comma, false if not.
* @private
*/
function isComma(token) {
return !!token && (token.type === "Punctuator") && (token.value === ",");
}
/**
* Reports a spacing error with an appropriate message.
* @param {ASTNode} node The binary expression node to report.
* @param {string} dir Is the error "before" or "after" the comma?
* @param {ASTNode} otherNode The node at the left or right of `node`
* @returns {void}
* @private
*/
function report(node, dir, otherNode) {
context.report({
node: node,
fix: function(fixer) {
if (options[dir]) {
if (dir === "before") {
return fixer.insertTextBefore(node, " ");
} else {
return fixer.insertTextAfter(node, " ");
}
} else {
var start, end;
var newText = "";
if (dir === "before") {
start = otherNode.range[1];
end = node.range[0];
} else {
start = node.range[1];
end = otherNode.range[0];
}
return fixer.replaceTextRange([start, end], newText);
}
},
message: options[dir] ?
"A space is required " + dir + " ','." :
"There should be no space " + dir + " ','."
});
}
/**
* Validates the spacing around a comma token.
* @param {Object} tokens - The tokens to be validated.
* @param {Token} tokens.comma The token representing the comma.
* @param {Token} [tokens.left] The last token before the comma.
* @param {Token} [tokens.right] The first token after the comma.
* @param {Token|ASTNode} reportItem The item to use when reporting an error.
* @returns {void}
* @private
*/
function validateCommaItemSpacing(tokens, reportItem) {
if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) &&
(options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma))
) {
report(reportItem, "before", tokens.left);
}
if (tokens.right && !options.after && tokens.right.type === "Line") {
return false;
}
if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) &&
(options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right))
) {
report(reportItem, "after", tokens.right);
}
}
/**
* Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list.
* @param {ASTNode} node An ArrayExpression or ArrayPattern node.
* @returns {void}
*/
function addNullElementsToIgnoreList(node) {
var previousToken = context.getFirstToken(node);
node.elements.forEach(function(element) {
var token;
if (element === null) {
token = context.getTokenAfter(previousToken);
if (isComma(token)) {
commaTokensToIgnore.push(token);
}
} else {
token = context.getTokenAfter(element);
}
previousToken = token;
});
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"Program:exit": function() {
var previousToken,
nextToken;
tokensAndComments.forEach(function(token, i) {
if (!isComma(token)) {
return;
}
if (token && token.type === "JSXText") {
return;
}
previousToken = tokensAndComments[i - 1];
nextToken = tokensAndComments[i + 1];
validateCommaItemSpacing({
comma: token,
left: isComma(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken,
right: isComma(nextToken) ? null : nextToken
}, token);
});
},
"ArrayExpression": addNullElementsToIgnoreList,
"ArrayPattern": addNullElementsToIgnoreList
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"before": {
"type": "boolean"
},
"after": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

186
node_modules/eslint/lib/rules/comma-style.js generated vendored Normal file
View File

@@ -0,0 +1,186 @@
/**
* @fileoverview Comma style - enforces comma styles of two types: last and first
* @author Vignesh Anand aka vegetableman
* @copyright 2014 Vignesh Anand. All rights reserved.
* @copyright 2015 Evan Simmons. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var style = context.options[0] || "last",
exceptions = {};
if (context.options.length === 2 && context.options[1].hasOwnProperty("exceptions")) {
exceptions = context.options[1].exceptions;
}
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Determines if a given token is a comma operator.
* @param {ASTNode} token The token to check.
* @returns {boolean} True if the token is a comma, false if not.
* @private
*/
function isComma(token) {
return !!token && (token.type === "Punctuator") && (token.value === ",");
}
/**
* Validates the spacing around single items in lists.
* @param {Token} previousItemToken The last token from the previous item.
* @param {Token} commaToken The token representing the comma.
* @param {Token} currentItemToken The first token of the current item.
* @param {Token} reportItem The item to use when reporting an error.
* @returns {void}
* @private
*/
function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) {
// if single line
if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
return;
} else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) &&
!astUtils.isTokenOnSameLine(previousItemToken, commaToken)) {
// lone comma
context.report(reportItem, {
line: commaToken.loc.end.line,
column: commaToken.loc.start.column
}, "Bad line breaking before and after ','.");
} else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
context.report(reportItem, "',' should be placed first.");
} else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) {
context.report(reportItem, {
line: commaToken.loc.end.line,
column: commaToken.loc.end.column
}, "',' should be placed last.");
}
}
/**
* Checks the comma placement with regards to a declaration/property/element
* @param {ASTNode} node The binary expression node to check
* @param {string} property The property of the node containing child nodes.
* @private
* @returns {void}
*/
function validateComma(node, property) {
var items = node[property],
arrayLiteral = (node.type === "ArrayExpression"),
previousItemToken;
if (items.length > 1 || arrayLiteral) {
// seed as opening [
previousItemToken = context.getFirstToken(node);
items.forEach(function(item) {
var commaToken = item ? context.getTokenBefore(item) : previousItemToken,
currentItemToken = item ? context.getFirstToken(item) : context.getTokenAfter(commaToken),
reportItem = item || currentItemToken;
/*
* This works by comparing three token locations:
* - previousItemToken is the last token of the previous item
* - commaToken is the location of the comma before the current item
* - currentItemToken is the first token of the current item
*
* These values get switched around if item is undefined.
* previousItemToken will refer to the last token not belonging
* to the current item, which could be a comma or an opening
* square bracket. currentItemToken could be a comma.
*
* All comparisons are done based on these tokens directly, so
* they are always valid regardless of an undefined item.
*/
if (isComma(commaToken)) {
validateCommaItemSpacing(previousItemToken, commaToken,
currentItemToken, reportItem);
}
previousItemToken = item ? context.getLastToken(item) : previousItemToken;
});
/*
* Special case for array literals that have empty last items, such
* as [ 1, 2, ]. These arrays only have two items show up in the
* AST, so we need to look at the token to verify that there's no
* dangling comma.
*/
if (arrayLiteral) {
var lastToken = context.getLastToken(node),
nextToLastToken = context.getTokenBefore(lastToken);
if (isComma(nextToLastToken)) {
validateCommaItemSpacing(
context.getTokenBefore(nextToLastToken),
nextToLastToken,
lastToken,
lastToken
);
}
}
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
var nodes = {};
if (!exceptions.VariableDeclaration) {
nodes.VariableDeclaration = function(node) {
validateComma(node, "declarations");
};
}
if (!exceptions.ObjectExpression) {
nodes.ObjectExpression = function(node) {
validateComma(node, "properties");
};
}
if (!exceptions.ArrayExpression) {
nodes.ArrayExpression = function(node) {
validateComma(node, "elements");
};
}
return nodes;
};
module.exports.schema = [
{
"enum": ["first", "last"]
},
{
"type": "object",
"properties": {
"exceptions": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
}
},
"additionalProperties": false
}
];

121
node_modules/eslint/lib/rules/complexity.js generated vendored Normal file
View File

@@ -0,0 +1,121 @@
/**
* @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity.
* Counts the number of if, conditional, for, whilte, try, switch/case,
* @author Patrick Brosset
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var THRESHOLD = context.options[0];
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
// Using a stack to store complexity (handling nested functions)
var fns = [];
/**
* When parsing a new function, store it in our function stack
* @returns {void}
* @private
*/
function startFunction() {
fns.push(1);
}
/**
* Evaluate the node at the end of function
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function endFunction(node) {
var complexity = fns.pop(),
name = "anonymous";
if (node.id) {
name = node.id.name;
} else if (node.parent.type === "MethodDefinition" || node.parent.type === "Property") {
name = node.parent.key.name;
}
if (complexity > THRESHOLD) {
context.report(node, "Function '{{name}}' has a complexity of {{complexity}}.", { name: name, complexity: complexity });
}
}
/**
* Increase the complexity of the function in context
* @returns {void}
* @private
*/
function increaseComplexity() {
if (fns.length) {
fns[fns.length - 1] ++;
}
}
/**
* Increase the switch complexity in context
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function increaseSwitchComplexity(node) {
// Avoiding `default`
if (node.test) {
increaseComplexity(node);
}
}
/**
* Increase the logical path complexity in context
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function increaseLogicalComplexity(node) {
// Avoiding &&
if (node.operator === "||") {
increaseComplexity(node);
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction,
"CatchClause": increaseComplexity,
"ConditionalExpression": increaseComplexity,
"LogicalExpression": increaseLogicalComplexity,
"ForStatement": increaseComplexity,
"ForInStatement": increaseComplexity,
"ForOfStatement": increaseComplexity,
"IfStatement": increaseComplexity,
"SwitchCase": increaseSwitchComplexity,
"WhileStatement": increaseComplexity,
"DoWhileStatement": increaseComplexity
};
};
module.exports.schema = [
{
"type": "integer"
}
];

View File

@@ -0,0 +1,153 @@
/**
* @fileoverview Disallows or enforces spaces inside computed properties.
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var sourceCode = context.getSourceCode();
var propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never"
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Reports that there shouldn't be a space after the first token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @param {Token} tokenAfter - The token after `token`.
* @returns {void}
*/
function reportNoBeginningSpace(node, token, tokenAfter) {
context.report({
node: node,
loc: token.loc.start,
message: "There should be no space after '" + token.value + "'",
fix: function(fixer) {
return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
}
});
}
/**
* Reports that there shouldn't be a space before the last token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @param {Token} tokenBefore - The token before `token`.
* @returns {void}
*/
function reportNoEndingSpace(node, token, tokenBefore) {
context.report({
node: node,
loc: token.loc.start,
message: "There should be no space before '" + token.value + "'",
fix: function(fixer) {
return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
}
});
}
/**
* Reports that there should be a space after the first token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportRequiredBeginningSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "A space is required after '" + token.value + "'",
fix: function(fixer) {
return fixer.insertTextAfter(token, " ");
}
});
}
/**
* Reports that there should be a space before the last token
* @param {ASTNode} node - The node to report in the event of an error.
* @param {Token} token - The token to use for the report.
* @returns {void}
*/
function reportRequiredEndingSpace(node, token) {
context.report({
node: node,
loc: token.loc.start,
message: "A space is required before '" + token.value + "'",
fix: function(fixer) {
return fixer.insertTextBefore(token, " ");
}
});
}
/**
* Returns a function that checks the spacing of a node on the property name
* that was passed in.
* @param {String} propertyName The property on the node to check for spacing
* @returns {Function} A function that will check spacing on a node
*/
function checkSpacing(propertyName) {
return function(node) {
if (!node.computed) {
return;
}
var property = node[propertyName];
var before = context.getTokenBefore(property),
first = context.getFirstToken(property),
last = context.getLastToken(property),
after = context.getTokenAfter(property);
if (astUtils.isTokenOnSameLine(before, first)) {
if (propertyNameMustBeSpaced) {
if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) {
reportRequiredBeginningSpace(node, before);
}
} else {
if (sourceCode.isSpaceBetweenTokens(before, first)) {
reportNoBeginningSpace(node, before, first);
}
}
}
if (astUtils.isTokenOnSameLine(last, after)) {
if (propertyNameMustBeSpaced) {
if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) {
reportRequiredEndingSpace(node, after);
}
} else {
if (sourceCode.isSpaceBetweenTokens(last, after)) {
reportNoEndingSpace(node, after, last);
}
}
}
};
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
Property: checkSpacing("key"),
MemberExpression: checkSpacing("property")
};
};
module.exports.schema = [
{
"enum": ["always", "never"]
}
];

75
node_modules/eslint/lib/rules/consistent-return.js generated vendored Normal file
View File

@@ -0,0 +1,75 @@
/**
* @fileoverview Rule to flag consistent return values
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var functions = [];
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Marks entrance into a function by pushing a new object onto the functions
* stack.
* @returns {void}
* @private
*/
function enterFunction() {
functions.push({});
}
/**
* Marks exit of a function by popping off the functions stack.
* @returns {void}
* @private
*/
function exitFunction() {
functions.pop();
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"Program": enterFunction,
"FunctionDeclaration": enterFunction,
"FunctionExpression": enterFunction,
"ArrowFunctionExpression": enterFunction,
"Program:exit": exitFunction,
"FunctionDeclaration:exit": exitFunction,
"FunctionExpression:exit": exitFunction,
"ArrowFunctionExpression:exit": exitFunction,
"ReturnStatement": function(node) {
var returnInfo = functions[functions.length - 1],
returnTypeDefined = "type" in returnInfo;
if (returnTypeDefined) {
if (returnInfo.type !== !!node.argument) {
context.report(node, "Expected " + (returnInfo.type ? "a" : "no") + " return value.");
}
} else {
returnInfo.type = !!node.argument;
}
}
};
};
module.exports.schema = [];

115
node_modules/eslint/lib/rules/consistent-this.js generated vendored Normal file
View File

@@ -0,0 +1,115 @@
/**
* @fileoverview Rule to enforce consistent naming of "this" context variables
* @author Raphael Pigulla
* @copyright 2015 Timothy Jones. All rights reserved.
* @copyright 2015 David Aurelio. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var alias = context.options[0];
/**
* Reports that a variable declarator or assignment expression is assigning
* a non-'this' value to the specified alias.
* @param {ASTNode} node - The assigning node.
* @returns {void}
*/
function reportBadAssignment(node) {
context.report(node,
"Designated alias '{{alias}}' is not assigned to 'this'.",
{ alias: alias });
}
/**
* Checks that an assignment to an identifier only assigns 'this' to the
* appropriate alias, and the alias is only assigned to 'this'.
* @param {ASTNode} node - The assigning node.
* @param {Identifier} name - The name of the variable assigned to.
* @param {Expression} value - The value of the assignment.
* @returns {void}
*/
function checkAssignment(node, name, value) {
var isThis = value.type === "ThisExpression";
if (name === alias) {
if (!isThis || node.operator && node.operator !== "=") {
reportBadAssignment(node);
}
} else if (isThis) {
context.report(node,
"Unexpected alias '{{name}}' for 'this'.", { name: name });
}
}
/**
* Ensures that a variable declaration of the alias in a program or function
* is assigned to the correct value.
* @returns {void}
*/
function ensureWasAssigned() {
var scope = context.getScope();
var variable = scope.set.get(alias);
if (!variable) {
return;
}
if (variable.defs.some(function(def) {
return def.node.type === "VariableDeclarator" &&
def.node.init !== null;
})) {
return;
}
var lookup = (variable.references.length === 0 && scope.type === "global") ? scope : variable;
// The alias has been declared and not assigned: check it was
// assigned later in the same scope.
if (!lookup.references.some(function(reference) {
var write = reference.writeExpr;
if (reference.from === scope &&
write && write.type === "ThisExpression" &&
write.parent.operator === "=") {
return true;
}
})) {
variable.defs.map(function(def) {
return def.node;
}).forEach(reportBadAssignment);
}
}
return {
"Program:exit": ensureWasAssigned,
"FunctionExpression:exit": ensureWasAssigned,
"FunctionDeclaration:exit": ensureWasAssigned,
"VariableDeclarator": function(node) {
var id = node.id;
var isDestructuring =
id.type === "ArrayPattern" || id.type === "ObjectPattern";
if (node.init !== null && !isDestructuring) {
checkAssignment(node, id.name, node.init);
}
},
"AssignmentExpression": function(node) {
if (node.left.type === "Identifier") {
checkAssignment(node, node.left.name, node.right);
}
}
};
};
module.exports.schema = [
{
"type": "string"
}
];

108
node_modules/eslint/lib/rules/constructor-super.js generated vendored Normal file
View File

@@ -0,0 +1,108 @@
/**
* @fileoverview A rule to verify `super()` callings in constructor.
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Searches a class node from ancestors of a node.
* @param {Node} node - A node to get.
* @returns {ClassDeclaration|ClassExpression|null} the found class node or `null`.
*/
function getClassInAncestor(node) {
while (node) {
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
return node;
}
node = node.parent;
}
/* istanbul ignore next */
return null;
}
/**
* Checks whether or not a node is the null literal.
* @param {Node} node - A node to check.
* @returns {boolean} whether or not a node is the null literal.
*/
function isNullLiteral(node) {
return node && node.type === "Literal" && node.value === null;
}
/**
* Checks whether or not the current traversal context is on constructors.
* @param {{scope: Scope}} item - A checking context to check.
* @returns {boolean} whether or not the current traversal context is on constructors.
*/
function isOnConstructor(item) {
return item && item.scope === context.getScope().variableScope.upper.variableScope;
}
// A stack for checking context.
var stack = [];
return {
/**
* Start checking.
* @param {MethodDefinition} node - A target node.
* @returns {void}
*/
"MethodDefinition": function(node) {
if (node.kind !== "constructor") {
return;
}
stack.push({
superCallings: [],
scope: context.getScope().variableScope
});
},
/**
* Checks the result, then reports invalid/missing `super()`.
* @param {MethodDefinition} node - A target node.
* @returns {void}
*/
"MethodDefinition:exit": function(node) {
if (node.kind !== "constructor") {
return;
}
var result = stack.pop();
var classNode = getClassInAncestor(node);
/* istanbul ignore if */
if (!classNode) {
return;
}
if (classNode.superClass === null || isNullLiteral(classNode.superClass)) {
result.superCallings.forEach(function(superCalling) {
context.report(superCalling, "unexpected `super()`.");
});
} else if (result.superCallings.length === 0) {
context.report(node.key, "this constructor requires `super()`.");
}
},
/**
* Checks the result of checking, then reports invalid/missing `super()`.
* @param {MethodDefinition} node - A target node.
* @returns {void}
*/
"CallExpression": function(node) {
var item = stack[stack.length - 1];
if (isOnConstructor(item) && node.callee.type === "Super") {
item.superCallings.push(node);
}
}
};
};
module.exports.schema = [];

294
node_modules/eslint/lib/rules/curly.js generated vendored Normal file
View File

@@ -0,0 +1,294 @@
/**
* @fileoverview Rule to flag statements without curly braces
* @author Nicholas C. Zakas
* @copyright 2015 Ivan Nikulin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var multiOnly = (context.options[0] === "multi");
var multiLine = (context.options[0] === "multi-line");
var multiOrNest = (context.options[0] === "multi-or-nest");
var consistent = (context.options[1] === "consistent");
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Determines if a given node is a one-liner that's on the same line as it's preceding code.
* @param {ASTNode} node The node to check.
* @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code.
* @private
*/
function isCollapsedOneLiner(node) {
var before = context.getTokenBefore(node),
last = context.getLastToken(node);
return before.loc.start.line === last.loc.end.line;
}
/**
* Determines if a given node is a one-liner.
* @param {ASTNode} node The node to check.
* @returns {boolean} True if the node is a one-liner.
* @private
*/
function isOneLiner(node) {
var first = context.getFirstToken(node),
last = context.getLastToken(node);
return first.loc.start.line === last.loc.end.line;
}
/**
* Gets the `else` keyword token of a given `IfStatement` node.
* @param {ASTNode} node - A `IfStatement` node to get.
* @returns {Token} The `else` keyword token.
*/
function getElseKeyword(node) {
var sourceCode = context.getSourceCode();
var token = sourceCode.getTokenAfter(node.consequent);
while (token.type !== "Keyword" || token.value !== "else") {
token = sourceCode.getTokenAfter(token);
}
return token;
}
/**
* Checks a given IfStatement node requires braces of the consequent chunk.
* This returns `true` when below:
*
* 1. The given node has the `alternate` node.
* 2. There is a `IfStatement` which doesn't have `alternate` node in the
* trailing statement chain of the `consequent` node.
*
* @param {ASTNode} node - A IfStatement node to check.
* @returns {boolean} `true` if the node requires braces of the consequent chunk.
*/
function requiresBraceOfConsequent(node) {
if (node.alternate && node.consequent.type === "BlockStatement") {
if (node.consequent.body.length >= 2) {
return true;
}
node = node.consequent.body[0];
while (node) {
if (node.type === "IfStatement" && !node.alternate) {
return true;
}
node = astUtils.getTrailingStatement(node);
}
}
return false;
}
/**
* Reports "Expected { after ..." error
* @param {ASTNode} node The node to report.
* @param {string} name The name to report.
* @param {string} suffix Additional string to add to the end of a report.
* @returns {void}
* @private
*/
function reportExpectedBraceError(node, name, suffix) {
context.report({
node: node,
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
message: "Expected { after '{{name}}'{{suffix}}.",
data: {
name: name,
suffix: (suffix ? " " + suffix : "")
}
});
}
/**
* Reports "Unnecessary { after ..." error
* @param {ASTNode} node The node to report.
* @param {string} name The name to report.
* @param {string} suffix Additional string to add to the end of a report.
* @returns {void}
* @private
*/
function reportUnnecessaryBraceError(node, name, suffix) {
context.report({
node: node,
loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
message: "Unnecessary { after '{{name}}'{{suffix}}.",
data: {
name: name,
suffix: (suffix ? " " + suffix : "")
}
});
}
/**
* Prepares to check the body of a node to see if it's a block statement.
* @param {ASTNode} node The node to report if there's a problem.
* @param {ASTNode} body The body node to check for blocks.
* @param {string} name The name to report if there's a problem.
* @param {string} suffix Additional string to add to the end of a report.
* @returns {object} a prepared check object, with "actual", "expected", "check" properties.
* "actual" will be `true` or `false` whether the body is already a block statement.
* "expected" will be `true` or `false` if the body should be a block statement or not, or
* `null` if it doesn't matter, depending on the rule options. It can be modified to change
* the final behavior of "check".
* "check" will be a function reporting appropriate problems depending on the other
* properties.
*/
function prepareCheck(node, body, name, suffix) {
var hasBlock = (body.type === "BlockStatement");
var expected = null;
if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) {
expected = true;
} else if (multiOnly) {
if (hasBlock && body.body.length === 1) {
expected = false;
}
} else if (multiLine) {
if (!isCollapsedOneLiner(body)) {
expected = true;
}
} else if (multiOrNest) {
if (hasBlock && body.body.length === 1 && isOneLiner(body.body[0])) {
expected = false;
} else if (!isOneLiner(body)) {
expected = true;
}
} else {
expected = true;
}
return {
actual: hasBlock,
expected: expected,
check: function() {
if (this.expected !== null && this.expected !== this.actual) {
if (this.expected) {
reportExpectedBraceError(node, name, suffix);
} else {
reportUnnecessaryBraceError(node, name, suffix);
}
}
}
};
}
/**
* Prepares to check the bodies of a "if", "else if" and "else" chain.
* @param {ASTNode} node The first IfStatement node of the chain.
* @returns {object[]} prepared checks for each body of the chain. See `prepareCheck` for more
* information.
*/
function prepareIfChecks(node) {
var preparedChecks = [];
do {
preparedChecks.push(prepareCheck(node, node.consequent, "if", "condition"));
if (node.alternate && node.alternate.type !== "IfStatement") {
preparedChecks.push(prepareCheck(node, node.alternate, "else"));
break;
}
node = node.alternate;
} while (node);
if (consistent) {
// If any node should have or already have braces, make sure they all have braces.
// If all nodes shouldn't have braces, make sure they don't.
var expected = preparedChecks.some(function(preparedCheck) {
if (preparedCheck.expected !== null) {
return preparedCheck.expected;
}
return preparedCheck.actual;
});
preparedChecks.forEach(function(preparedCheck) {
preparedCheck.expected = expected;
});
}
return preparedChecks;
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"IfStatement": function(node) {
if (node.parent.type !== "IfStatement") {
prepareIfChecks(node).forEach(function(preparedCheck) {
preparedCheck.check();
});
}
},
"WhileStatement": function(node) {
prepareCheck(node, node.body, "while", "condition").check();
},
"DoWhileStatement": function(node) {
prepareCheck(node, node.body, "do").check();
},
"ForStatement": function(node) {
prepareCheck(node, node.body, "for", "condition").check();
},
"ForInStatement": function(node) {
prepareCheck(node, node.body, "for-in").check();
},
"ForOfStatement": function(node) {
prepareCheck(node, node.body, "for-of").check();
}
};
};
module.exports.schema = {
"anyOf": [
{
"type": "array",
"items": [
{
"enum": [0, 1, 2]
},
{
"enum": ["all"]
}
],
"minItems": 1,
"maxItems": 2
},
{
"type": "array",
"items": [
{
"enum": [0, 1, 2]
},
{
"enum": ["multi", "multi-line", "multi-or-nest"]
},
{
"enum": ["consistent"]
}
],
"minItems": 1,
"maxItems": 3
}
]
};

66
node_modules/eslint/lib/rules/default-case.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
/**
* @fileoverview require default case in switch statements
* @author Aliaksei Shytkin
*/
"use strict";
var COMMENT_VALUE = "no default";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Shortcut to get last element of array
* @param {*[]} collection Array
* @returns {*} Last element
*/
function last(collection) {
return collection[collection.length - 1];
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"SwitchStatement": function(node) {
if (!node.cases.length) {
// skip check of empty switch because there is no easy way
// to extract comments inside it now
return;
}
var hasDefault = node.cases.some(function(v) {
return v.test === null;
});
if (!hasDefault) {
var comment;
var comments;
var lastCase = last(node.cases);
comments = context.getComments(lastCase).trailing;
if (comments.length) {
comment = last(comments);
}
if (!comment || comment.value.trim() !== COMMENT_VALUE) {
context.report(node, "Expected a default case.");
}
}
}
};
};
module.exports.schema = [];

60
node_modules/eslint/lib/rules/dot-location.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
/**
* @fileoverview Validates newlines before and after dots
* @author Greg Cochard
* @copyright 2015 Greg Cochard
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var config = context.options[0],
// default to onObject if no preference is passed
onObject = config === "object" || !config;
/**
* Reports if the dot between object and property is on the correct loccation.
* @param {ASTNode} obj The object owning the property.
* @param {ASTNode} prop The property of the object.
* @param {ASTNode} node The corresponding node of the token.
* @returns {void}
*/
function checkDotLocation(obj, prop, node) {
var dot = context.getTokenBefore(prop);
if (dot.type === "Punctuator" && dot.value === ".") {
if (onObject) {
if (!astUtils.isTokenOnSameLine(obj, dot)) {
context.report(node, dot.loc.start, "Expected dot to be on same line as object.");
}
} else if (!astUtils.isTokenOnSameLine(dot, prop)) {
context.report(node, dot.loc.start, "Expected dot to be on same line as property.");
}
}
}
/**
* Checks the spacing of the dot within a member expression.
* @param {ASTNode} node The node to check.
* @returns {void}
*/
function checkNode(node) {
checkDotLocation(node.object, node.property, node);
}
return {
"MemberExpression": checkNode
};
};
module.exports.schema = [
{
"enum": ["object", "property"]
}
];

59
node_modules/eslint/lib/rules/dot-notation.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
/**
* @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible.
* @author Josh Perez
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
var keywords = require("../util/keywords");
module.exports = function(context) {
var options = context.options[0] || {};
var allowKeywords = options.allowKeywords === void 0 || !!options.allowKeywords;
var allowPattern;
if (options.allowPattern) {
allowPattern = new RegExp(options.allowPattern);
}
return {
"MemberExpression": function(node) {
if (
node.computed &&
node.property.type === "Literal" &&
validIdentifier.test(node.property.value) &&
(allowKeywords || keywords.indexOf("" + node.property.value) === -1)
) {
if (!(allowPattern && allowPattern.test(node.property.value))) {
context.report(node, "[" + JSON.stringify(node.property.value) + "] is better written in dot notation.");
}
}
if (
!allowKeywords &&
!node.computed &&
keywords.indexOf("" + node.property.name) !== -1
) {
context.report(node, "." + node.property.name + " is a syntax error.");
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"allowKeywords": {
"type": "boolean"
},
"allowPattern": {
"type": "string"
}
},
"additionalProperties": false
}
];

51
node_modules/eslint/lib/rules/eol-last.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
/**
* @fileoverview Require file to end with single newline.
* @author Nodeca Team <https://github.com/nodeca>
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"Program": function checkBadEOF(node) {
// Get the whole source code, not for node only.
var src = context.getSource(),
location = {column: 1},
linebreakStyle = context.options[0] || "unix",
linebreak = linebreakStyle === "unix" ? "\n" : "\r\n";
if (src.length === 0) {
return;
}
if (src[src.length - 1] !== "\n") {
// file is not newline-terminated
location.line = src.split(/\n/g).length;
context.report({
node: node,
loc: location,
message: "Newline required at end of file but not found.",
fix: function(fixer) {
return fixer.insertTextAfterRange([0, src.length], linebreak);
}
});
}
}
};
};
module.exports.schema = [
{
"enum": ["unix", "windows"]
}
];

120
node_modules/eslint/lib/rules/eqeqeq.js generated vendored Normal file
View File

@@ -0,0 +1,120 @@
/**
* @fileoverview Rule to flag statements that use != and == instead of !== and ===
* @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var sourceCode = context.getSourceCode(),
replacements = {
"==": "===",
"!=": "!=="
};
/**
* Checks if an expression is a typeof expression
* @param {ASTNode} node The node to check
* @returns {boolean} if the node is a typeof expression
*/
function isTypeOf(node) {
return node.type === "UnaryExpression" && node.operator === "typeof";
}
/**
* Checks if either operand of a binary expression is a typeof operation
* @param {ASTNode} node The node to check
* @returns {boolean} if one of the operands is typeof
* @private
*/
function isTypeOfBinary(node) {
return isTypeOf(node.left) || isTypeOf(node.right);
}
/**
* Checks if operands are literals of the same type (via typeof)
* @param {ASTNode} node The node to check
* @returns {boolean} if operands are of same type
* @private
*/
function areLiteralsAndSameType(node) {
return node.left.type === "Literal" && node.right.type === "Literal" &&
typeof node.left.value === typeof node.right.value;
}
/**
* Checks if one of the operands is a literal null
* @param {ASTNode} node The node to check
* @returns {boolean} if operands are null
* @private
*/
function isNullCheck(node) {
return (node.right.type === "Literal" && node.right.value === null) ||
(node.left.type === "Literal" && node.left.value === null);
}
/**
* Gets the location (line and column) of the binary expression's operator
* @param {ASTNode} node The binary expression node to check
* @param {String} operator The operator to find
* @returns {Object} { line, column } location of operator
* @private
*/
function getOperatorLocation(node) {
var opToken = context.getTokenAfter(node.left);
return {line: opToken.loc.start.line, column: opToken.loc.start.column};
}
return {
"BinaryExpression": function(node) {
if (node.operator !== "==" && node.operator !== "!=") {
return;
}
if (context.options[0] === "smart" && (isTypeOfBinary(node) ||
areLiteralsAndSameType(node) || isNullCheck(node))) {
return;
}
if (context.options[0] === "allow-null" && isNullCheck(node)) {
return;
}
context.report({
node: node,
loc: getOperatorLocation(node),
message: "Expected '{{op}}=' and instead saw '{{op}}'.",
data: { op: node.operator },
fix: function(fixer) {
var tokens = sourceCode.getTokensBetween(node.left, node.right),
opToken,
i;
for (i = 0; i < tokens.length; ++i) {
if (tokens[i].value === node.operator) {
opToken = tokens[i];
break;
}
}
return fixer.replaceTextRange(opToken.range, replacements[node.operator]);
}
});
}
};
};
module.exports.schema = [
{
"enum": ["smart", "allow-null"]
}
];

45
node_modules/eslint/lib/rules/func-names.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
/**
* @fileoverview Rule to warn when a function expression does not have a name.
* @author Kyle T. Nunery
* @copyright 2015 Brandon Mills. All rights reserved.
* @copyright 2014 Kyle T. Nunery. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Determines whether the current FunctionExpression node is a get, set, or
* shorthand method in an object literal or a class.
* @returns {boolean} True if the node is a get, set, or shorthand method.
*/
function isObjectOrClassMethod() {
var parent = context.getAncestors().pop();
return (parent.type === "MethodDefinition" || (
parent.type === "Property" && (
parent.method ||
parent.kind === "get" ||
parent.kind === "set"
)
));
}
return {
"FunctionExpression": function(node) {
var name = node.id && node.id.name;
if (!name && !isObjectOrClassMethod()) {
context.report(node, "Missing function expression name.");
}
}
};
};
module.exports.schema = [];

84
node_modules/eslint/lib/rules/func-style.js generated vendored Normal file
View File

@@ -0,0 +1,84 @@
/**
* @fileoverview Rule to enforce a particular function style
* @author Nicholas C. Zakas
* @copyright 2013 Nicholas C. Zakas. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var style = context.options[0],
allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions === true,
enforceDeclarations = (style === "declaration"),
stack = [];
var nodesToCheck = {
"Program": function() {
stack = [];
},
"FunctionDeclaration": function(node) {
stack.push(false);
if (!enforceDeclarations) {
context.report(node, "Expected a function expression.");
}
},
"FunctionDeclaration:exit": function() {
stack.pop();
},
"FunctionExpression": function(node) {
stack.push(false);
if (enforceDeclarations && node.parent.type === "VariableDeclarator") {
context.report(node.parent, "Expected a function declaration.");
}
},
"FunctionExpression:exit": function() {
stack.pop();
},
"ThisExpression": function() {
if (stack.length > 0) {
stack[stack.length - 1] = true;
}
}
};
if (!allowArrowFunctions) {
nodesToCheck.ArrowFunctionExpression = function() {
stack.push(false);
};
nodesToCheck["ArrowFunctionExpression:exit"] = function(node) {
var hasThisExpr = stack.pop();
if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") {
context.report(node.parent, "Expected a function declaration.");
}
};
}
return nodesToCheck;
};
module.exports.schema = [
{
"enum": ["declaration", "expression"]
},
{
"type": "object",
"properties": {
"allowArrowFunctions": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

114
node_modules/eslint/lib/rules/generator-star-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,114 @@
/**
* @fileoverview Rule to check the spacing around the * in generator functions.
* @author Jamund Ferguson
* @copyright 2015 Brandon Mills. All rights reserved.
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var mode = (function(option) {
if (!option || typeof option === "string") {
return {
before: { before: true, after: false },
after: { before: false, after: true },
both: { before: true, after: true },
neither: { before: false, after: false }
}[option || "before"];
}
return option;
}(context.options[0]));
/**
* Checks the spacing between two tokens before or after the star token.
* @param {string} side Either "before" or "after".
* @param {Token} leftToken `function` keyword token if side is "before", or
* star token if side is "after".
* @param {Token} rightToken Star token if side is "before", or identifier
* token if side is "after".
* @returns {void}
*/
function checkSpacing(side, leftToken, rightToken) {
if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) {
var after = leftToken.value === "*";
var spaceRequired = mode[side];
var node = after ? leftToken : rightToken;
var type = spaceRequired ? "Missing" : "Unexpected";
var message = type + " space " + side + " *.";
context.report({
node: node,
message: message,
fix: function(fixer) {
if (spaceRequired) {
if (after) {
return fixer.insertTextAfter(node, " ");
}
return fixer.insertTextBefore(node, " ");
}
return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
}
});
}
}
/**
* Enforces the spacing around the star if node is a generator function.
* @param {ASTNode} node A function expression or declaration node.
* @returns {void}
*/
function checkFunction(node) {
var prevToken, starToken, nextToken;
if (!node.generator) {
return;
}
if (node.parent.method || node.parent.type === "MethodDefinition") {
starToken = context.getTokenBefore(node, 1);
} else {
starToken = context.getFirstToken(node, 1);
}
// Only check before when preceded by `function` keyword
prevToken = context.getTokenBefore(starToken);
if (prevToken.value === "function" || prevToken.value === "static") {
checkSpacing("before", prevToken, starToken);
}
// Only check after when followed by an identifier
nextToken = context.getTokenAfter(starToken);
if (nextToken.type === "Identifier") {
checkSpacing("after", starToken, nextToken);
}
}
return {
"FunctionDeclaration": checkFunction,
"FunctionExpression": checkFunction
};
};
module.exports.schema = [
{
"oneOf": [
{
"enum": ["before", "after", "both", "neither"]
},
{
"type": "object",
"properties": {
"before": {"type": "boolean"},
"after": {"type": "boolean"}
},
"additionalProperties": false
}
]
}
];

35
node_modules/eslint/lib/rules/global-require.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
/**
* @fileoverview Rule for disallowing require() outside of the top-level module context
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/
"use strict";
var ACCEPTABLE_PARENTS = [
"AssignmentExpression",
"VariableDeclarator",
"MemberExpression",
"ExpressionStatement",
"CallExpression",
"ConditionalExpression",
"Program",
"VariableDeclaration"
];
module.exports = function(context) {
return {
"CallExpression": function(node) {
if (node.callee.name === "require") {
var isGoodRequire = context.getAncestors().every(function(parent) {
return ACCEPTABLE_PARENTS.indexOf(parent.type) > -1;
});
if (!isGoodRequire) {
context.report(node, "Unexpected require().");
}
}
}
};
};
module.exports.schema = [];

32
node_modules/eslint/lib/rules/guard-for-in.js generated vendored Normal file
View File

@@ -0,0 +1,32 @@
/**
* @fileoverview Rule to flag for-in loops without if statements inside
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"ForInStatement": function(node) {
/*
* If the for-in statement has {}, then the real body is the body
* of the BlockStatement. Otherwise, just use body as provided.
*/
var body = node.body.type === "BlockStatement" ? node.body.body[0] : node.body;
if (body && body.type !== "IfStatement") {
context.report(node, "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.");
}
}
};
};
module.exports.schema = [];

81
node_modules/eslint/lib/rules/handle-callback-err.js generated vendored Normal file
View File

@@ -0,0 +1,81 @@
/**
* @fileoverview Ensure handling of errors when we know they exist.
* @author Jamund Ferguson
* @copyright 2015 Mathias Schreck.
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var errorArgument = context.options[0] || "err";
/**
* Checks if the given argument should be interpreted as a regexp pattern.
* @param {string} stringToCheck The string which should be checked.
* @returns {boolean} Whether or not the string should be interpreted as a pattern.
*/
function isPattern(stringToCheck) {
var firstChar = stringToCheck[0];
return firstChar === "^";
}
/**
* Checks if the given name matches the configured error argument.
* @param {string} name The name which should be compared.
* @returns {boolean} Whether or not the given name matches the configured error variable name.
*/
function matchesConfiguredErrorName(name) {
if (isPattern(errorArgument)) {
var regexp = new RegExp(errorArgument);
return regexp.test(name);
}
return name === errorArgument;
}
/**
* Get the parameters of a given function scope.
* @param {object} scope The function scope.
* @returns {array} All parameters of the given scope.
*/
function getParameters(scope) {
return scope.variables.filter(function(variable) {
return variable.defs[0] && variable.defs[0].type === "Parameter";
});
}
/**
* Check to see if we're handling the error object properly.
* @param {ASTNode} node The AST node to check.
* @returns {void}
*/
function checkForError(node) {
var scope = context.getScope(),
parameters = getParameters(scope),
firstParameter = parameters[0];
if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) {
if (firstParameter.references.length === 0) {
context.report(node, "Expected error to be handled.");
}
}
}
return {
"FunctionDeclaration": checkForError,
"FunctionExpression": checkForError,
"ArrowFunctionExpression": checkForError
};
};
module.exports.schema = [
{
"type": "string"
}
];

106
node_modules/eslint/lib/rules/id-length.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
/**
* @fileoverview Rule that warns when identifier names are shorter or longer
* than the values provided in configuration.
* @author Burak Yigit Kaya aka BYK
* @copyright 2015 Burak Yigit Kaya. All rights reserved.
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var options = context.options[0] || {};
var minLength = typeof options.min !== "undefined" ? options.min : 2;
var maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
var properties = options.properties !== "never";
var exceptions = (options.exceptions ? options.exceptions : [])
.reduce(function(obj, item) {
obj[item] = true;
return obj;
}, {});
var SUPPORTED_EXPRESSIONS = {
"MemberExpression": properties && function(parent) {
return !parent.computed && (
// regular property assignment
parent.parent.left === parent || (
// or the last identifier in an ObjectPattern destructuring
parent.parent.type === "Property" && parent.parent.value === parent &&
parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent
)
);
},
"AssignmentPattern": function(parent, node) {
return parent.left === node;
},
"VariableDeclarator": function(parent, node) {
return parent.id === node;
},
"Property": properties && function(parent, node) {
return parent.key === node;
},
"ImportDefaultSpecifier": true,
"RestElement": true,
"FunctionExpression": true,
"ArrowFunctionExpression": true,
"ClassDeclaration": true,
"FunctionDeclaration": true,
"MethodDefinition": true,
"CatchClause": true
};
return {
Identifier: function(node) {
var name = node.name;
var parent = node.parent;
var isShort = name.length < minLength;
var isLong = name.length > maxLength;
if (!(isShort || isLong) || exceptions[name]) {
return; // Nothing to report
}
var isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) {
context.report(
node,
isShort ?
"Identifier name '{{name}}' is too short. (< {{min}})" :
"Identifier name '{{name}}' is too long. (> {{max}})",
{ name: name, min: minLength, max: maxLength }
);
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"min": {
"type": "number"
},
"max": {
"type": "number"
},
"exceptions": {
"type": "array",
"uniqueItems": true,
"items": {
"type": "string"
}
},
"properties": {
"enum": ["always", "never"]
}
},
"additionalProperties": false
}
];

129
node_modules/eslint/lib/rules/id-match.js generated vendored Normal file
View File

@@ -0,0 +1,129 @@
/**
* @fileoverview Rule to flag non-matching identifiers
* @author Matthieu Larcher
* @copyright 2015 Matthieu Larcher. All rights reserved.
* See LICENSE in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
var pattern = context.options[0] || "^.+$",
regexp = new RegExp(pattern);
var options = context.options[1] || {},
properties = options.properties;
// cast to boolean and default to false
properties = !!properties;
/**
* Checks if a string matches the provided pattern
* @param {String} name The string to check.
* @returns {boolean} if the string is a match
* @private
*/
function isInvalid(name) {
return !regexp.test(name);
}
/**
* Verifies if we should report an error or not based on the effective
* parent node and the identifier name.
* @param {ASTNode} effectiveParent The effective parent node of the node to be reported
* @param {String} name The identifier name of the identifier node
* @returns {boolean} whether an error should be reported or not
*/
function shouldReport(effectiveParent, name) {
return effectiveParent.type !== "CallExpression"
&& effectiveParent.type !== "NewExpression" &&
isInvalid(name);
}
/**
* Reports an AST node as a rule violation.
* @param {ASTNode} node The node to report.
* @returns {void}
* @private
*/
function report(node) {
context.report(node, "Identifier '{{name}}' does not match the pattern '{{pattern}}'.", {
name: node.name,
pattern: pattern
});
}
return {
"Identifier": function(node) {
var name = node.name,
effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent;
// MemberExpressions get special rules
if (node.parent.type === "MemberExpression") {
// return early if properties is false
if (!properties) {
return;
}
// Always check object names
if (node.parent.object.type === "Identifier" &&
node.parent.object.name === node.name) {
if (isInvalid(name)) {
report(node);
}
// Report AssignmentExpressions only if they are the left side of the assignment
} else if (effectiveParent.type === "AssignmentExpression" &&
(effectiveParent.right.type !== "MemberExpression" ||
effectiveParent.left.type === "MemberExpression" &&
effectiveParent.left.property.name === node.name)) {
if (isInvalid(name)) {
report(node);
}
}
// Properties have their own rules
} else if (node.parent.type === "Property") {
// return early if properties is false
if (!properties) {
return;
}
if (shouldReport(effectiveParent, name)) {
report(node);
}
// Report anything that is a match and not a CallExpression
} else if (shouldReport(effectiveParent, name)) {
report(node);
}
}
};
};
module.exports.schema = [
{
"type": "string"
},
{
"type": "object",
"properties": {
"properties": {
"type": "boolean"
}
}
}
];

714
node_modules/eslint/lib/rules/indent.js generated vendored Normal file
View File

@@ -0,0 +1,714 @@
/**
* @fileoverview This option sets a specific tab width for your code
* This rule has been ported and modified from nodeca.
* @author Vitaly Puzrin
* @author Gyandeep Singh
* @copyright 2015 Vitaly Puzrin. All rights reserved.
* @copyright 2015 Gyandeep Singh. All rights reserved.
Copyright (C) 2014 by Vitaly Puzrin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
var util = require("util");
var assign = require("object-assign");
module.exports = function(context) {
var MESSAGE = "Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.";
var DEFAULT_VARIABLE_INDENT = 1;
var indentType = "space";
var indentSize = 4;
var options = {
SwitchCase: 0,
VariableDeclarator: {
var: DEFAULT_VARIABLE_INDENT,
let: DEFAULT_VARIABLE_INDENT,
const: DEFAULT_VARIABLE_INDENT
}
};
if (context.options.length) {
if (context.options[0] === "tab") {
indentSize = 1;
indentType = "tab";
} else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") {
indentSize = context.options[0];
indentType = "space";
}
if (context.options[1]) {
var opts = context.options[1];
options.SwitchCase = opts.SwitchCase || 0;
var variableDeclaratorRules = opts.VariableDeclarator;
if (typeof variableDeclaratorRules === "number") {
options.VariableDeclarator = {
var: variableDeclaratorRules,
let: variableDeclaratorRules,
const: variableDeclaratorRules
};
} else if (typeof variableDeclaratorRules === "object") {
assign(options.VariableDeclarator, variableDeclaratorRules);
}
}
}
var indentPattern = {
normal: indentType === "space" ? /^ +/ : /^\t+/,
excludeCommas: indentType === "space" ? /^[ ,]+/ : /^[\t,]+/
};
var caseIndentStore = {};
/**
* Reports a given indent violation and properly pluralizes the message
* @param {ASTNode} node Node violating the indent rule
* @param {int} needed Expected indentation character count
* @param {int} gotten Indentation character count in the actual node/code
* @param {Object=} loc Error line and column location
* @param {boolean} isLastNodeCheck Is the error for last node check
* @returns {void}
*/
function report(node, needed, gotten, loc, isLastNodeCheck) {
var msgContext = {
needed: needed,
type: indentType,
characters: needed === 1 ? "character" : "characters",
gotten: gotten
};
var indentChar = indentType === "space" ? " " : "\t";
/**
* Responsible for fixing the indentation issue fix
* @returns {Function} function to be executed by the fixer
* @private
*/
function getFixerFunction() {
var rangeToFix = [];
if (needed > gotten) {
var spaces = "" + new Array(needed - gotten + 1).join(indentChar); // replace with repeat in future
if (isLastNodeCheck === true) {
rangeToFix = [
node.range[1] - 1,
node.range[1] - 1
];
} else {
rangeToFix = [
node.range[0],
node.range[0]
];
}
return function(fixer) {
return fixer.insertTextBeforeRange(rangeToFix, spaces);
};
} else {
if (isLastNodeCheck === true) {
rangeToFix = [
node.range[1] - (gotten - needed) - 1,
node.range[1] - 1
];
} else {
rangeToFix = [
node.range[0] - (gotten - needed),
node.range[0]
];
}
return function(fixer) {
return fixer.removeRange(rangeToFix);
};
}
}
if (loc) {
context.report({
node: node,
loc: loc,
message: MESSAGE,
data: msgContext,
fix: getFixerFunction()
});
} else {
context.report({
node: node,
message: MESSAGE,
data: msgContext,
fix: getFixerFunction()
});
}
}
/**
* Get node indent
* @param {ASTNode|Token} node Node to examine
* @param {boolean} [byLastLine=false] get indent of node's last line
* @param {boolean} [excludeCommas=false] skip comma on start of line
* @returns {int} Indent
*/
function getNodeIndent(node, byLastLine, excludeCommas) {
var token = byLastLine ? context.getLastToken(node) : context.getFirstToken(node);
var src = context.getSource(token, token.loc.start.column);
var regExp = excludeCommas ? indentPattern.excludeCommas : indentPattern.normal;
var indent = regExp.exec(src);
return indent ? indent[0].length : 0;
}
/**
* Checks node is the first in its own start line. By default it looks by start line.
* @param {ASTNode} node The node to check
* @param {boolean} [byEndLocation=false] Lookup based on start position or end
* @returns {boolean} true if its the first in the its start line
*/
function isNodeFirstInLine(node, byEndLocation) {
var firstToken = byEndLocation === true ? context.getLastToken(node, 1) : context.getTokenBefore(node),
startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line,
endLine = firstToken ? firstToken.loc.end.line : -1;
return startLine !== endLine;
}
/**
* Check indent for nodes list
* @param {ASTNode[]} nodes list of node objects
* @param {int} indent needed indent
* @param {boolean} [excludeCommas=false] skip comma on start of line
* @returns {void}
*/
function checkNodesIndent(nodes, indent, excludeCommas) {
nodes.forEach(function(node) {
var nodeIndent = getNodeIndent(node, false, excludeCommas);
if (
node.type !== "ArrayExpression" && node.type !== "ObjectExpression" &&
nodeIndent !== indent && isNodeFirstInLine(node)
) {
report(node, indent, nodeIndent);
}
});
}
/**
* Check last node line indent this detects, that block closed correctly
* @param {ASTNode} node Node to examine
* @param {int} lastLineIndent needed indent
* @returns {void}
*/
function checkLastNodeLineIndent(node, lastLineIndent) {
var lastToken = context.getLastToken(node);
var endIndent = getNodeIndent(lastToken, true);
if (endIndent !== lastLineIndent && isNodeFirstInLine(node, true)) {
report(
node,
lastLineIndent,
endIndent,
{ line: lastToken.loc.start.line, column: lastToken.loc.start.column },
true
);
}
}
/**
* Check first node line indent is correct
* @param {ASTNode} node Node to examine
* @param {int} firstLineIndent needed indent
* @returns {void}
*/
function checkFirstNodeLineIndent(node, firstLineIndent) {
var startIndent = getNodeIndent(node, false);
if (startIndent !== firstLineIndent && isNodeFirstInLine(node)) {
report(
node,
firstLineIndent,
startIndent,
{ line: node.loc.start.line, column: node.loc.start.column }
);
}
}
/**
* Returns the VariableDeclarator based on the current node
* if not present then return null
* @param {ASTNode} node node to examine
* @returns {ASTNode|void} if found then node otherwise null
*/
function getVariableDeclaratorNode(node) {
var parent = node.parent;
while (parent.type !== "VariableDeclarator" && parent.type !== "Program") {
parent = parent.parent;
}
return parent.type === "VariableDeclarator" ? parent : null;
}
/**
* Check to see if the node is part of the multi-line variable declaration.
* Also if its on the same line as the varNode
* @param {ASTNode} node node to check
* @param {ASTNode} varNode variable declaration node to check against
* @returns {boolean} True if all the above condition satisfy
*/
function isNodeInVarOnTop(node, varNode) {
return varNode &&
varNode.parent.loc.start.line === node.loc.start.line &&
varNode.parent.declarations.length > 1;
}
/**
* Check to see if the argument before the callee node is multi-line and
* there should only be 1 argument before the callee node
* @param {ASTNode} node node to check
* @returns {boolean} True if arguments are multi-line
*/
function isArgBeforeCalleeNodeMultiline(node) {
var parent = node.parent;
if (parent.arguments.length >= 2 && parent.arguments[1] === node) {
return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line;
}
return false;
}
/**
* Check indent for function block content
* @param {ASTNode} node node to examine
* @returns {void}
*/
function checkIndentInFunctionBlock(node) {
// Search first caller in chain.
// Ex.:
//
// Models <- Identifier
// .User
// .find()
// .exec(function() {
// // function body
// });
//
// Looks for 'Models'
var calleeNode = node.parent; // FunctionExpression
var indent;
if (calleeNode.parent &&
(calleeNode.parent.type === "Property" ||
calleeNode.parent.type === "ArrayExpression")) {
// If function is part of array or object, comma can be put at left
indent = getNodeIndent(calleeNode, false, true);
} else {
// If function is standalone, simple calculate indent
indent = getNodeIndent(calleeNode);
}
if (calleeNode.parent.type === "CallExpression") {
var calleeParent = calleeNode.parent;
if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") {
if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) {
indent = getNodeIndent(calleeParent);
}
} else {
if (isArgBeforeCalleeNodeMultiline(calleeNode) &&
calleeParent.callee.loc.start.line === calleeParent.callee.loc.end.line &&
!isNodeFirstInLine(calleeNode)) {
indent = getNodeIndent(calleeParent);
}
}
}
// function body indent should be indent + indent size
indent += indentSize;
// check if the node is inside a variable
var parentVarNode = getVariableDeclaratorNode(node);
if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) {
indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind];
}
if (node.body.length > 0) {
checkNodesIndent(node.body, indent);
}
checkLastNodeLineIndent(node, indent - indentSize);
}
/**
* Checks if the given node starts and ends on the same line
* @param {ASTNode} node The node to check
* @returns {boolean} Whether or not the block starts and ends on the same line.
*/
function isSingleLineNode(node) {
var lastToken = context.getLastToken(node),
startLine = node.loc.start.line,
endLine = lastToken.loc.end.line;
return startLine === endLine;
}
/**
* Check to see if the first element inside an array is an object and on the same line as the node
* If the node is not an array then it will return false.
* @param {ASTNode} node node to check
* @returns {boolean} success/failure
*/
function isFirstArrayElementOnSameLine(node) {
if (node.type === "ArrayExpression" && node.elements[0]) {
return node.elements[0].loc.start.line === node.loc.start.line && node.elements[0].type === "ObjectExpression";
} else {
return false;
}
}
/**
* Check indent for array block content or object block content
* @param {ASTNode} node node to examine
* @returns {void}
*/
function checkIndentInArrayOrObjectBlock(node) {
// Skip inline
if (isSingleLineNode(node)) {
return;
}
var elements = (node.type === "ArrayExpression") ? node.elements : node.properties;
// filter out empty elements example would be [ , 2] so remove first element as espree considers it as null
elements = elements.filter(function(elem) {
return elem !== null;
});
// Skip if first element is in same line with this node
if (elements.length > 0 && elements[0].loc.start.line === node.loc.start.line) {
return;
}
var nodeIndent;
var elementsIndent;
var parentVarNode = getVariableDeclaratorNode(node);
// TODO - come up with a better strategy in future
if (isNodeFirstInLine(node)) {
var parent = node.parent;
var effectiveParent = parent;
if (parent.type === "MemberExpression") {
if (isNodeFirstInLine(parent)) {
effectiveParent = parent.parent.parent;
} else {
effectiveParent = parent.parent;
}
}
nodeIndent = getNodeIndent(effectiveParent);
if (parentVarNode && parentVarNode.loc.start.line !== node.loc.start.line) {
if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) {
nodeIndent = nodeIndent + (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]);
} else if (parent.loc.start.line !== node.loc.start.line && parentVarNode === parentVarNode.parent.declarations[0]) {
nodeIndent = nodeIndent + indentSize;
}
} else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && effectiveParent.type !== "MemberExpression" && effectiveParent.type !== "ExpressionStatement" && effectiveParent.type !== "AssignmentExpression" && effectiveParent.type !== "Property") {
nodeIndent = nodeIndent + indentSize;
}
elementsIndent = nodeIndent + indentSize;
checkFirstNodeLineIndent(node, nodeIndent);
} else {
nodeIndent = getNodeIndent(node);
elementsIndent = nodeIndent + indentSize;
}
// check if the node is a multiple variable declaration, if yes then make sure indentation takes into account
// variable indentation concept
if (isNodeInVarOnTop(node, parentVarNode)) {
elementsIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind];
}
// Comma can be placed before property name
checkNodesIndent(elements, elementsIndent, true);
if (elements.length > 0) {
// Skip last block line check if last item in same line
if (elements[elements.length - 1].loc.end.line === node.loc.end.line) {
return;
}
}
checkLastNodeLineIndent(node, elementsIndent - indentSize);
}
/**
* Check if the node or node body is a BlockStatement or not
* @param {ASTNode} node node to test
* @returns {boolean} True if it or its body is a block statement
*/
function isNodeBodyBlock(node) {
return node.type === "BlockStatement" || (node.body && node.body.type === "BlockStatement") ||
(node.consequent && node.consequent.type === "BlockStatement");
}
/**
* Check indentation for blocks
* @param {ASTNode} node node to check
* @returns {void}
*/
function blockIndentationCheck(node) {
// Skip inline blocks
if (isSingleLineNode(node)) {
return;
}
if (node.parent && (
node.parent.type === "FunctionExpression" ||
node.parent.type === "FunctionDeclaration" ||
node.parent.type === "ArrowFunctionExpression"
)) {
checkIndentInFunctionBlock(node);
return;
}
var indent;
var nodesToCheck = [];
// For this statements we should check indent from statement begin
// (not from block begin)
var statementsWithProperties = [
"IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement"
];
if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) {
indent = getNodeIndent(node.parent);
} else {
indent = getNodeIndent(node);
}
if (node.type === "IfStatement" && node.consequent.type !== "BlockStatement") {
nodesToCheck = [node.consequent];
} else if (util.isArray(node.body)) {
nodesToCheck = node.body;
} else {
nodesToCheck = [node.body];
}
if (nodesToCheck.length > 0) {
checkNodesIndent(nodesToCheck, indent + indentSize);
}
if (node.type === "BlockStatement") {
checkLastNodeLineIndent(node, indent);
}
}
/**
* Filter out the elements which are on the same line of each other or the node.
* basically have only 1 elements from each line except the variable declaration line.
* @param {ASTNode} node Variable declaration node
* @returns {ASTNode[]} Filtered elements
*/
function filterOutSameLineVars(node) {
return node.declarations.reduce(function(finalCollection, elem) {
var lastElem = finalCollection[finalCollection.length - 1];
if ((elem.loc.start.line !== node.loc.start.line && !lastElem) ||
(lastElem && lastElem.loc.start.line !== elem.loc.start.line)) {
finalCollection.push(elem);
}
return finalCollection;
}, []);
}
/**
* Check indentation for variable declarations
* @param {ASTNode} node node to examine
* @returns {void}
*/
function checkIndentInVariableDeclarations(node) {
var elements = filterOutSameLineVars(node);
var nodeIndent = getNodeIndent(node);
var lastElement = elements[elements.length - 1];
var elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind];
// Comma can be placed before declaration
checkNodesIndent(elements, elementsIndent, true);
// Only check the last line if there is any token after the last item
if (context.getLastToken(node).loc.end.line <= lastElement.loc.end.line) {
return;
}
var tokenBeforeLastElement = context.getTokenBefore(lastElement);
if (tokenBeforeLastElement.value === ",") {
// Special case for comma-first syntax where the semicolon is indented
checkLastNodeLineIndent(node, getNodeIndent(tokenBeforeLastElement));
} else {
checkLastNodeLineIndent(node, elementsIndent - indentSize);
}
}
/**
* Check and decide whether to check for indentation for blockless nodes
* Scenarios are for or while statements without braces around them
* @param {ASTNode} node node to examine
* @returns {void}
*/
function blockLessNodes(node) {
if (node.body.type !== "BlockStatement") {
blockIndentationCheck(node);
}
}
/**
* Returns the expected indentation for the case statement
* @param {ASTNode} node node to examine
* @param {int} [switchIndent] indent for switch statement
* @returns {int} indent size
*/
function expectedCaseIndent(node, switchIndent) {
var switchNode = (node.type === "SwitchStatement") ? node : node.parent;
var caseIndent;
if (caseIndentStore[switchNode.loc.start.line]) {
return caseIndentStore[switchNode.loc.start.line];
} else {
if (typeof switchIndent === "undefined") {
switchIndent = getNodeIndent(switchNode);
}
if (switchNode.cases.length > 0 && options.SwitchCase === 0) {
caseIndent = switchIndent;
} else {
caseIndent = switchIndent + (indentSize * options.SwitchCase);
}
caseIndentStore[switchNode.loc.start.line] = caseIndent;
return caseIndent;
}
}
return {
"Program": function(node) {
if (node.body.length > 0) {
// Root nodes should have no indent
checkNodesIndent(node.body, getNodeIndent(node));
}
},
"BlockStatement": blockIndentationCheck,
"WhileStatement": blockLessNodes,
"ForStatement": blockLessNodes,
"ForInStatement": blockLessNodes,
"ForOfStatement": blockLessNodes,
"DoWhileStatement": blockLessNodes,
"IfStatement": function(node) {
if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) {
blockIndentationCheck(node);
}
},
"VariableDeclaration": function(node) {
if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) {
checkIndentInVariableDeclarations(node);
}
},
"ObjectExpression": function(node) {
checkIndentInArrayOrObjectBlock(node);
},
"ArrayExpression": function(node) {
checkIndentInArrayOrObjectBlock(node);
},
"SwitchStatement": function(node) {
// Switch is not a 'BlockStatement'
var switchIndent = getNodeIndent(node);
var caseIndent = expectedCaseIndent(node, switchIndent);
checkNodesIndent(node.cases, caseIndent);
checkLastNodeLineIndent(node, switchIndent);
},
"SwitchCase": function(node) {
// Skip inline cases
if (isSingleLineNode(node)) {
return;
}
var caseIndent = expectedCaseIndent(node);
checkNodesIndent(node.consequent, caseIndent + indentSize);
}
};
};
module.exports.schema = [
{
"oneOf": [
{
"enum": ["tab"]
},
{
"type": "integer"
}
]
},
{
"type": "object",
"properties": {
"SwitchCase": {
"type": "integer"
},
"VariableDeclarator": {
"type": ["integer", "object"],
"properties": {
"var": {
"type": "integer"
},
"let": {
"type": "integer"
},
"const": {
"type": "integer"
}
}
}
},
"additionalProperties": false
}
];

120
node_modules/eslint/lib/rules/init-declarations.js generated vendored Normal file
View File

@@ -0,0 +1,120 @@
/**
* @fileoverview A rule to control the style of variable initializations.
* @author Colin Ihrig
* @copyright 2015 Colin Ihrig. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether or not a given node is a for loop.
* @param {ASTNode} block - A node to check.
* @returns {boolean} `true` when the node is a for loop.
*/
function isForLoop(block) {
return block.type === "ForInStatement" ||
block.type === "ForOfStatement" ||
block.type === "ForStatement";
}
/**
* Checks whether or not a given declarator node has its initializer.
* @param {ASTNode} node - A declarator node to check.
* @returns {boolean} `true` when the node has its initializer.
*/
function isInitialized(node) {
var declaration = node.parent;
var block = declaration.parent;
if (isForLoop(block)) {
if (block.type === "ForStatement") {
return block.init === declaration;
}
return block.left === declaration;
}
return Boolean(node.init);
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var MODE_ALWAYS = "always",
MODE_NEVER = "never";
var mode = context.options[0] || MODE_ALWAYS;
var params = context.options[1] || {};
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"VariableDeclaration:exit": function(node) {
var kind = node.kind,
declarations = node.declarations;
for (var i = 0; i < declarations.length; ++i) {
var declaration = declarations[i],
id = declaration.id,
initialized = isInitialized(declaration),
isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent);
if (id.type !== "Identifier") {
continue;
}
if (mode === MODE_ALWAYS && !initialized) {
context.report(declaration, "Variable '" + id.name + "' should be initialized on declaration.");
} else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) {
context.report(declaration, "Variable '" + id.name + "' should not be initialized on declaration.");
}
}
}
};
};
module.exports.schema = {
"anyOf": [
{
"type": "array",
"items": [
{
"enum": [0, 1, 2]
},
{
"enum": ["always"]
}
],
"minItems": 1,
"maxItems": 2
},
{
"type": "array",
"items": [
{
"enum": [0, 1, 2]
},
{
"enum": ["never"]
},
{
"type": "object",
"properties": {
"ignoreForLoopInit": {
"type": "boolean"
}
},
"additionalProperties": false
}
],
"minItems": 1,
"maxItems": 3
}
]
};

63
node_modules/eslint/lib/rules/jsx-quotes.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
/**
* @fileoverview A rule to ensure consistent quotes used in jsx syntax.
* @author Mathias Schreck <https://github.com/lo1tuma>
* @copyright 2015 Mathias Schreck
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var QUOTE_SETTINGS = {
"prefer-double": {
quote: "\"",
description: "singlequote"
},
"prefer-single": {
quote: "'",
description: "doublequote"
}
};
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var quoteOption = context.options[0] || "prefer-double",
setting = QUOTE_SETTINGS[quoteOption];
/**
* Checks if the given string literal node uses the expected quotes
* @param {ASTNode} node - A string literal node.
* @returns {boolean} Whether or not the string literal used the expected quotes.
* @public
*/
function usesExpectedQuotes(node) {
return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote);
}
return {
"JSXAttribute": function(node) {
var attributeValue = node.value;
if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) {
context.report(attributeValue, "Unexpected usage of {{description}}.", setting);
}
}
};
};
module.exports.schema = [
{
"enum": [ "prefer-single", "prefer-double" ]
}
];

339
node_modules/eslint/lib/rules/key-spacing.js generated vendored Normal file
View File

@@ -0,0 +1,339 @@
/**
* @fileoverview Rule to specify spacing of object literal keys and values
* @author Brandon Mills
* @copyright 2014 Brandon Mills. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether a string contains a line terminator as defined in
* http://www.ecma-international.org/ecma-262/5.1/#sec-7.3
* @param {string} str String to test.
* @returns {boolean} True if str contains a line terminator.
*/
function containsLineTerminator(str) {
return /[\n\r\u2028\u2029]/.test(str);
}
/**
* Gets the last element of an array.
* @param {Array} arr An array.
* @returns {any} Last element of arr.
*/
function last(arr) {
return arr[arr.length - 1];
}
/**
* Checks whether a property is a member of the property group it follows.
* @param {ASTNode} lastMember The last Property known to be in the group.
* @param {ASTNode} candidate The next Property that might be in the group.
* @returns {boolean} True if the candidate property is part of the group.
*/
function continuesPropertyGroup(lastMember, candidate) {
var groupEndLine = lastMember.loc.start.line,
candidateStartLine = candidate.loc.start.line,
comments, i;
if (candidateStartLine - groupEndLine <= 1) {
return true;
}
// Check that the first comment is adjacent to the end of the group, the
// last comment is adjacent to the candidate property, and that successive
// comments are adjacent to each other.
comments = candidate.leadingComments;
if (
comments &&
comments[0].loc.start.line - groupEndLine <= 1 &&
candidateStartLine - last(comments).loc.end.line <= 1
) {
for (i = 1; i < comments.length; i++) {
if (comments[i].loc.start.line - comments[i - 1].loc.end.line > 1) {
return false;
}
}
return true;
}
return false;
}
/**
* Checks whether a node is contained on a single line.
* @param {ASTNode} node AST Node being evaluated.
* @returns {boolean} True if the node is a single line.
*/
function isSingleLine(node) {
return (node.loc.end.line === node.loc.start.line);
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
var messages = {
key: "{{error}} space after {{computed}}key \"{{key}}\".",
value: "{{error}} space before value for {{computed}}key \"{{key}}\"."
};
module.exports = function(context) {
/**
* OPTIONS
* "key-spacing": [2, {
* beforeColon: false,
* afterColon: true,
* align: "colon" // Optional, or "value"
* }
*/
var options = context.options[0] || {},
align = options.align,
mode = options.mode || "strict",
beforeColon = +!!options.beforeColon, // Defaults to false
afterColon = +!(options.afterColon === false); // Defaults to true
/**
* Starting from the given a node (a property.key node here) looks forward
* until it finds the last token before a colon punctuator and returns it.
* @param {ASTNode} node The node to start looking from.
* @returns {ASTNode} The last token before a colon punctuator.
*/
function getLastTokenBeforeColon(node) {
var prevNode;
while (node && (node.type !== "Punctuator" || node.value !== ":")) {
prevNode = node;
node = context.getTokenAfter(node);
}
return prevNode;
}
/**
* Gets an object literal property's key as the identifier name or string value.
* @param {ASTNode} property Property node whose key to retrieve.
* @returns {string} The property's key.
*/
function getKey(property) {
var key = property.key;
if (property.computed) {
return context.getSource().slice(key.range[0], key.range[1]);
}
return property.key.name || property.key.value;
}
/**
* Reports an appropriately-formatted error if spacing is incorrect on one
* side of the colon.
* @param {ASTNode} property Key-value pair in an object literal.
* @param {string} side Side being verified - either "key" or "value".
* @param {string} whitespace Actual whitespace string.
* @param {int} expected Expected whitespace length.
* @returns {void}
*/
function report(property, side, whitespace, expected) {
var diff = whitespace.length - expected,
key = property.key,
firstTokenAfterColon = context.getTokenAfter(key, 1),
location = side === "key" ? key.loc.start : firstTokenAfterColon.loc.start;
if ((diff && mode === "strict" || diff < 0 && mode === "minimum") &&
!(expected && containsLineTerminator(whitespace))
) {
context.report(property[side], location, messages[side], {
error: diff > 0 ? "Extra" : "Missing",
computed: property.computed ? "computed " : "",
key: getKey(property)
});
}
}
/**
* Gets the number of characters in a key, including quotes around string
* keys and braces around computed property keys.
* @param {ASTNode} property Property of on object literal.
* @returns {int} Width of the key.
*/
function getKeyWidth(property) {
var startToken, endToken;
// Ignore shorthand methods and properties, as they have no colon
if (property.method || property.shorthand) {
return 0;
}
startToken = context.getFirstToken(property);
endToken = getLastTokenBeforeColon(property.key);
return endToken.range[1] - startToken.range[0];
}
/**
* Gets the whitespace around the colon in an object literal property.
* @param {ASTNode} property Property node from an object literal.
* @returns {Object} Whitespace before and after the property's colon.
*/
function getPropertyWhitespace(property) {
var whitespace = /(\s*):(\s*)/.exec(context.getSource().slice(
property.key.range[1], property.value.range[0]
));
if (whitespace) {
return {
beforeColon: whitespace[1],
afterColon: whitespace[2]
};
}
}
/**
* Creates groups of properties.
* @param {ASTNode} node ObjectExpression node being evaluated.
* @returns {Array.<ASTNode[]>} Groups of property AST node lists.
*/
function createGroups(node) {
if (node.properties.length === 1) {
return [node.properties];
}
return node.properties.reduce(function(groups, property) {
var currentGroup = last(groups),
prev = last(currentGroup);
if (!prev || continuesPropertyGroup(prev, property)) {
currentGroup.push(property);
} else {
groups.push([property]);
}
return groups;
}, [[]]);
}
/**
* Verifies correct vertical alignment of a group of properties.
* @param {ASTNode[]} properties List of Property AST nodes.
* @returns {void}
*/
function verifyGroupAlignment(properties) {
var length = properties.length,
widths = properties.map(getKeyWidth), // Width of keys, including quotes
targetWidth = Math.max.apply(null, widths),
i, property, whitespace, width;
// Conditionally include one space before or after colon
targetWidth += (align === "colon" ? beforeColon : afterColon);
for (i = 0; i < length; i++) {
property = properties[i];
whitespace = getPropertyWhitespace(property);
if (!whitespace) {
continue; // Object literal getters/setters lack a colon
}
width = widths[i];
if (align === "value") {
report(property, "key", whitespace.beforeColon, beforeColon);
report(property, "value", whitespace.afterColon, targetWidth - width);
} else { // align = "colon"
report(property, "key", whitespace.beforeColon, targetWidth - width);
report(property, "value", whitespace.afterColon, afterColon);
}
}
}
/**
* Verifies vertical alignment, taking into account groups of properties.
* @param {ASTNode} node ObjectExpression node being evaluated.
* @returns {void}
*/
function verifyAlignment(node) {
createGroups(node).forEach(function(group) {
verifyGroupAlignment(group);
});
}
/**
* Verifies spacing of property conforms to specified options.
* @param {ASTNode} node Property node being evaluated.
* @returns {void}
*/
function verifySpacing(node) {
var whitespace = getPropertyWhitespace(node);
if (whitespace) { // Object literal getters/setters lack colons
report(node, "key", whitespace.beforeColon, beforeColon);
report(node, "value", whitespace.afterColon, afterColon);
}
}
/**
* Verifies spacing of each property in a list.
* @param {ASTNode[]} properties List of Property AST nodes.
* @returns {void}
*/
function verifyListSpacing(properties) {
var length = properties.length;
for (var i = 0; i < length; i++) {
verifySpacing(properties[i]);
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
if (align) { // Verify vertical alignment
return {
"ObjectExpression": function(node) {
if (isSingleLine(node)) {
verifyListSpacing(node.properties);
} else {
verifyAlignment(node);
}
}
};
} else { // Strictly obey beforeColon and afterColon in each property
return {
"Property": function(node) {
verifySpacing(node);
}
};
}
};
module.exports.schema = [
{
"type": "object",
"properties": {
"align": {
"enum": ["colon", "value"]
},
"mode": {
"enum": ["strict", "minimum"]
},
"beforeColon": {
"type": "boolean"
},
"afterColon": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

79
node_modules/eslint/lib/rules/linebreak-style.js generated vendored Normal file
View File

@@ -0,0 +1,79 @@
/**
* @fileoverview Rule to forbid mixing LF and LFCR line breaks.
* @author Erik Mueller
* @copyright 2015 Varun Verma. All rights reserverd.
* @copyright 2015 James Whitney. All rights reserved.
* @copyright 2015 Erik Mueller. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var EXPECTED_LF_MSG = "Expected linebreaks to be 'LF' but found 'CRLF'.",
EXPECTED_CRLF_MSG = "Expected linebreaks to be 'CRLF' but found 'LF'.";
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Builds a fix function that replaces text at the specified range in the source text.
* @param {int[]} range The range to replace
* @param {string} text The text to insert.
* @returns {function} Fixer function
* @private
*/
function createFix(range, text) {
return function(fixer) {
return fixer.replaceTextRange(range, text);
};
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"Program": function checkForlinebreakStyle(node) {
var linebreakStyle = context.options[0] || "unix",
expectedLF = linebreakStyle === "unix",
expectedLFChars = expectedLF ? "\n" : "\r\n",
source = context.getSource(),
pattern = /\r\n|\r|\n|\u2028|\u2029/g,
match,
index,
range;
var i = 0;
while ((match = pattern.exec(source)) !== null) {
i++;
if (match[0] === expectedLFChars) {
continue;
}
index = match.index;
range = [index, index + match[0].length];
context.report({
node: node,
loc: {
line: i,
column: context.getSourceLines()[i - 1].length
},
message: expectedLF ? EXPECTED_LF_MSG : EXPECTED_CRLF_MSG,
fix: createFix(range, expectedLFChars)
});
}
}
};
};
module.exports.schema = [
{
"enum": ["unix", "windows"]
}
];

334
node_modules/eslint/lib/rules/lines-around-comment.js generated vendored Normal file
View File

@@ -0,0 +1,334 @@
/**
* @fileoverview Enforces empty lines around comments.
* @author Jamund Ferguson
* @copyright 2015 Mathieu M-Gosselin. All rights reserved.
* @copyright 2015 Jamund Ferguson. All rights reserved.
* @copyright 2015 Gyandeep Singh. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var assign = require("object-assign");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Return an array with with any line numbers that are empty.
* @param {Array} lines An array of each line of the file.
* @returns {Array} An array of line numbers.
*/
function getEmptyLineNums(lines) {
var emptyLines = lines.map(function(line, i) {
return {
code: line.trim(),
num: i + 1
};
}).filter(function(line) {
return !line.code;
}).map(function(line) {
return line.num;
});
return emptyLines;
}
/**
* Return an array with with any line numbers that contain comments.
* @param {Array} comments An array of comment nodes.
* @returns {Array} An array of line numbers.
*/
function getCommentLineNums(comments) {
var lines = [];
comments.forEach(function(token) {
var start = token.loc.start.line;
var end = token.loc.end.line;
lines.push(start, end);
});
return lines;
}
/**
* Determines if a value is an array.
* @param {number} val The value we wish to check for in the array..
* @param {Array} array An array.
* @returns {boolean} True if the value is in the array..
*/
function contains(val, array) {
return array.indexOf(val) > -1;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var options = context.options[0] ? assign({}, context.options[0]) : {};
options.beforeLineComment = options.beforeLineComment || false;
options.afterLineComment = options.afterLineComment || false;
options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true;
options.afterBlockComment = options.afterBlockComment || false;
options.allowBlockStart = options.allowBlockStart || false;
options.allowBlockEnd = options.allowBlockEnd || false;
var sourceCode = context.getSourceCode();
/**
* Returns whether or not comments are on lines starting with or ending with code
* @param {ASTNode} node The comment node to check.
* @returns {boolean} True if the comment is not alone.
*/
function codeAroundComment(node) {
var token;
token = node;
do {
token = sourceCode.getTokenOrCommentBefore(token);
} while (token && (token.type === "Block" || token.type === "Line"));
if (token && token.loc.end.line === node.loc.start.line) {
return true;
}
token = node;
do {
token = sourceCode.getTokenOrCommentAfter(token);
} while (token && (token.type === "Block" || token.type === "Line"));
if (token && token.loc.start.line === node.loc.end.line) {
return true;
}
return false;
}
/**
* Returns whether or not comments are inside a node type or not.
* @param {ASTNode} node The Comment node.
* @param {ASTNode} parent The Comment parent node.
* @param {string} nodeType The parent type to check against.
* @returns {boolean} True if the comment is inside nodeType.
*/
function isCommentInsideNodeType(node, parent, nodeType) {
return parent.type === nodeType ||
(parent.body && parent.body.type === nodeType) ||
(parent.consequent && parent.consequent.type === nodeType);
}
/**
* Returns whether or not comments are at the parent start or not.
* @param {ASTNode} node The Comment node.
* @param {string} nodeType The parent type to check against.
* @returns {boolean} True if the comment is at parent start.
*/
function isCommentAtParentStart(node, nodeType) {
var ancestors = context.getAncestors();
var parent;
if (ancestors.length) {
parent = ancestors.pop();
}
return parent && isCommentInsideNodeType(node, parent, nodeType) &&
node.loc.start.line - parent.loc.start.line === 1;
}
/**
* Returns whether or not comments are at the parent end or not.
* @param {ASTNode} node The Comment node.
* @param {string} nodeType The parent type to check against.
* @returns {boolean} True if the comment is at parent end.
*/
function isCommentAtParentEnd(node, nodeType) {
var ancestors = context.getAncestors();
var parent;
if (ancestors.length) {
parent = ancestors.pop();
}
return parent && isCommentInsideNodeType(node, parent, nodeType) &&
parent.loc.end.line - node.loc.end.line === 1;
}
/**
* Returns whether or not comments are at the block start or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at block start.
*/
function isCommentAtBlockStart(node) {
return isCommentAtParentStart(node, "ClassBody") || isCommentAtParentStart(node, "BlockStatement");
}
/**
* Returns whether or not comments are at the block end or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at block end.
*/
function isCommentAtBlockEnd(node) {
return isCommentAtParentEnd(node, "ClassBody") || isCommentAtParentEnd(node, "BlockStatement");
}
/**
* Returns whether or not comments are at the object start or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at object start.
*/
function isCommentAtObjectStart(node) {
return isCommentAtParentStart(node, "ObjectExpression") || isCommentAtParentStart(node, "ObjectPattern");
}
/**
* Returns whether or not comments are at the object end or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at object end.
*/
function isCommentAtObjectEnd(node) {
return isCommentAtParentEnd(node, "ObjectExpression") || isCommentAtParentEnd(node, "ObjectPattern");
}
/**
* Returns whether or not comments are at the array start or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at array start.
*/
function isCommentAtArrayStart(node) {
return isCommentAtParentStart(node, "ArrayExpression") || isCommentAtParentStart(node, "ArrayPattern");
}
/**
* Returns whether or not comments are at the array end or not.
* @param {ASTNode} node The Comment node.
* @returns {boolean} True if the comment is at array end.
*/
function isCommentAtArrayEnd(node) {
return isCommentAtParentEnd(node, "ArrayExpression") || isCommentAtParentEnd(node, "ArrayPattern");
}
/**
* Checks if a comment node has lines around it (ignores inline comments)
* @param {ASTNode} node The Comment node.
* @param {Object} opts Options to determine the newline.
* @param {Boolean} opts.after Should have a newline after this line.
* @param {Boolean} opts.before Should have a newline before this line.
* @returns {void}
*/
function checkForEmptyLine(node, opts) {
var lines = context.getSourceLines(),
numLines = lines.length + 1,
comments = context.getAllComments(),
commentLines = getCommentLineNums(comments),
emptyLines = getEmptyLineNums(lines),
commentAndEmptyLines = commentLines.concat(emptyLines);
var after = opts.after,
before = opts.before;
var prevLineNum = node.loc.start.line - 1,
nextLineNum = node.loc.end.line + 1,
commentIsNotAlone = codeAroundComment(node);
var blockStartAllowed = options.allowBlockStart && isCommentAtBlockStart(node),
blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(node),
objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(node),
objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(node),
arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(node),
arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(node);
var exceptionStartAllowed = blockStartAllowed || objectStartAllowed || arrayStartAllowed;
var exceptionEndAllowed = blockEndAllowed || objectEndAllowed || arrayEndAllowed;
// ignore top of the file and bottom of the file
if (prevLineNum < 1) {
before = false;
}
if (nextLineNum >= numLines) {
after = false;
}
// we ignore all inline comments
if (commentIsNotAlone) {
return;
}
// check for newline before
if (!exceptionStartAllowed && before && !contains(prevLineNum, commentAndEmptyLines)) {
context.report(node, "Expected line before comment.");
}
// check for newline after
if (!exceptionEndAllowed && after && !contains(nextLineNum, commentAndEmptyLines)) {
context.report(node, "Expected line after comment.");
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"LineComment": function(node) {
if (options.beforeLineComment || options.afterLineComment) {
checkForEmptyLine(node, {
after: options.afterLineComment,
before: options.beforeLineComment
});
}
},
"BlockComment": function(node) {
if (options.beforeBlockComment || options.afterBlockComment) {
checkForEmptyLine(node, {
after: options.afterBlockComment,
before: options.beforeBlockComment
});
}
}
};
};
module.exports.schema = [
{
"type": "object",
"properties": {
"beforeBlockComment": {
"type": "boolean"
},
"afterBlockComment": {
"type": "boolean"
},
"beforeLineComment": {
"type": "boolean"
},
"afterLineComment": {
"type": "boolean"
},
"allowBlockStart": {
"type": "boolean"
},
"allowBlockEnd": {
"type": "boolean"
},
"allowObjectStart": {
"type": "boolean"
},
"allowObjectEnd": {
"type": "boolean"
},
"allowArrayStart": {
"type": "boolean"
},
"allowArrayEnd": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

110
node_modules/eslint/lib/rules/max-depth.js generated vendored Normal file
View File

@@ -0,0 +1,110 @@
/**
* @fileoverview A rule to set the maximum depth block can be nested in a function.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
var functionStack = [],
maxDepth = context.options[0] || 4;
/**
* When parsing a new function, store it in our function stack
* @returns {void}
* @private
*/
function startFunction() {
functionStack.push(0);
}
/**
* When parsing is done then pop out the reference
* @returns {void}
* @private
*/
function endFunction() {
functionStack.pop();
}
/**
* Save the block and Evaluate the node
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function pushBlock(node) {
var len = ++functionStack[functionStack.length - 1];
if (len > maxDepth) {
context.report(node, "Blocks are nested too deeply ({{depth}}).",
{ depth: len });
}
}
/**
* Pop the saved block
* @returns {void}
* @private
*/
function popBlock() {
functionStack[functionStack.length - 1]--;
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"Program": startFunction,
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"IfStatement": function(node) {
if (node.parent.type !== "IfStatement") {
pushBlock(node);
}
},
"SwitchStatement": pushBlock,
"TryStatement": pushBlock,
"DoWhileStatement": pushBlock,
"WhileStatement": pushBlock,
"WithStatement": pushBlock,
"ForStatement": pushBlock,
"ForInStatement": pushBlock,
"ForOfStatement": pushBlock,
"IfStatement:exit": popBlock,
"SwitchStatement:exit": popBlock,
"TryStatement:exit": popBlock,
"DoWhileStatement:exit": popBlock,
"WhileStatement:exit": popBlock,
"WithStatement:exit": popBlock,
"ForStatement:exit": popBlock,
"ForInStatement:exit": popBlock,
"ForOfStatement:exit": popBlock,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction,
"Program:exit": endFunction
};
};
module.exports.schema = [
{
"type": "integer"
}
];

165
node_modules/eslint/lib/rules/max-len.js generated vendored Normal file
View File

@@ -0,0 +1,165 @@
/**
* @fileoverview Rule to check for max length on a line.
* @author Matt DuVall <http://www.mattduvall.com>
* @copyright 2013 Matt DuVall. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
// takes some ideas from http://tools.ietf.org/html/rfc3986#appendix-B, however:
// - They're matching an entire string that we know is a URI
// - We're matching part of a string where we think there *might* be a URL
// - We're only concerned about URLs, as picking out any URI would cause too many false positives
// - We don't care about matching the entire URL, any small segment is fine
var URL_REGEXP = /[^:/?#]:\/\/[^?#]/;
/**
* Creates a string that is made up of repeating a given string a certain
* number of times. This uses exponentiation of squares to achieve significant
* performance gains over the more traditional implementation of such
* functionality.
* @param {string} str The string to repeat.
* @param {int} num The number of times to repeat the string.
* @returns {string} The created string.
* @private
*/
function stringRepeat(str, num) {
var result = "";
for (num |= 0; num > 0; num >>>= 1, str += str) {
if (num & 1) {
result += str;
}
}
return result;
}
var maxLength = context.options[0] || 80,
tabWidth = context.options[1] || 4,
ignoreOptions = context.options[2] || {},
ignorePattern = ignoreOptions.ignorePattern || null,
ignoreComments = ignoreOptions.ignoreComments || false,
ignoreUrls = ignoreOptions.ignoreUrls || false,
tabString = stringRepeat(" ", tabWidth);
if (ignorePattern) {
ignorePattern = new RegExp(ignorePattern);
}
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Tells if a given comment is trailing: it starts on the current line and
* extends to or past the end of the current line.
* @param {string} line The source line we want to check for a trailing comment on
* @param {number} lineNumber The one-indexed line number for line
* @param {ASTNode} comment The comment to inspect
* @returns {boolean} If the comment is trailing on the given line
*/
function isTrailingComment(line, lineNumber, comment) {
return comment &&
(comment.loc.start.line <= lineNumber && lineNumber <= comment.loc.end.line) &&
(comment.loc.end.line > lineNumber || comment.loc.end.column === line.length);
}
/**
* Gets the line after the comment and any remaining trailing whitespace is
* stripped.
* @param {string} line The source line with a trailing comment
* @param {number} lineNumber The one-indexed line number this is on
* @param {ASTNode} comment The comment to remove
* @returns {string} Line without comment and trailing whitepace
*/
function stripTrailingComment(line, lineNumber, comment) {
if (comment.loc.start.line < lineNumber) {
// this entire line is a comment
return "";
} else {
// loc.column is zero-indexed
return line.slice(0, comment.loc.start.column).replace(/\s+$/, "");
}
}
/**
* Check the program for max length
* @param {ASTNode} node Node to examine
* @returns {void}
* @private
*/
function checkProgramForMaxLength(node) {
// split (honors line-ending)
var lines = context.getSourceLines(),
// list of comments to ignore
comments = ignoreComments ? context.getAllComments() : [],
// we iterate over comments in parallel with the lines
commentsIndex = 0;
lines.forEach(function(line, i) {
// i is zero-indexed, line numbers are one-indexed
var lineNumber = i + 1;
// we can short-circuit the comment checks if we're already out of comments to check
if (commentsIndex < comments.length) {
// iterate over comments until we find one past the current line
do {
var comment = comments[++commentsIndex];
} while (comment && comment.loc.start.line <= lineNumber);
// and step back by one
comment = comments[--commentsIndex];
if (isTrailingComment(line, lineNumber, comment)) {
line = stripTrailingComment(line, lineNumber, comment);
}
}
if (ignorePattern && ignorePattern.test(line) ||
ignoreUrls && URL_REGEXP.test(line)) {
// ignore this line
return;
}
// replace the tabs
if (line.replace(/\t/g, tabString).length > maxLength) {
context.report(node, { line: lineNumber, column: 0 }, "Line " + (i + 1) + " exceeds the maximum line length of " + maxLength + ".");
}
});
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"Program": checkProgramForMaxLength
};
};
module.exports.schema = [
{
"type": "integer",
"minimum": 0
},
{
"type": "integer",
"minimum": 0
},
{
"type": "object",
"properties": {
"ignorePattern": {
"type": "string"
},
"ignoreComments": {
"type": "boolean"
},
"ignoreUrls": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

73
node_modules/eslint/lib/rules/max-nested-callbacks.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
/**
* @fileoverview Rule to enforce a maximum number of nested callbacks.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------
var THRESHOLD = context.options[0] || 10;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
var callbackStack = [];
/**
* Checks a given function node for too many callbacks.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkFunction(node) {
var parent = node.parent;
if (parent.type === "CallExpression") {
callbackStack.push(node);
}
if (callbackStack.length > THRESHOLD) {
var opts = {num: callbackStack.length, max: THRESHOLD};
context.report(node, "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.", opts);
}
}
/**
* Pops the call stack.
* @returns {void}
* @private
*/
function popStack() {
callbackStack.pop();
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"ArrowFunctionExpression": checkFunction,
"ArrowFunctionExpression:exit": popStack,
"FunctionExpression": checkFunction,
"FunctionExpression:exit": popStack
};
};
module.exports.schema = [
{
"type": "integer"
}
];

45
node_modules/eslint/lib/rules/max-params.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
/**
* @fileoverview Rule to flag when a function has too many parameters
* @author Ilya Volodin
* @copyright 2014 Nicholas C. Zakas. All rights reserved.
* @copyright 2013 Ilya Volodin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var numParams = context.options[0] || 3;
/**
* Checks a function to see if it has too many parameters.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkFunction(node) {
if (node.params.length > numParams) {
context.report(node, "This function has too many parameters ({{count}}). Maximum allowed is {{max}}.", {
count: node.params.length,
max: numParams
});
}
}
return {
"FunctionDeclaration": checkFunction,
"ArrowFunctionExpression": checkFunction,
"FunctionExpression": checkFunction
};
};
module.exports.schema = [
{
"type": "integer"
}
];

78
node_modules/eslint/lib/rules/max-statements.js generated vendored Normal file
View File

@@ -0,0 +1,78 @@
/**
* @fileoverview A rule to set the maximum number of statements in a function.
* @author Ian Christian Myers
* @copyright 2013 Ian Christian Myers. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
var functionStack = [],
maxStatements = context.options[0] || 10;
/**
* When parsing a new function, store it in our function stack
* @returns {void}
* @private
*/
function startFunction() {
functionStack.push(0);
}
/**
* Evaluate the node at the end of function
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function endFunction(node) {
var count = functionStack.pop();
if (count > maxStatements) {
context.report(node, "This function has too many statements ({{count}}). Maximum allowed is {{max}}.",
{ count: count, max: maxStatements });
}
}
/**
* Increment the count of the functions
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function countStatements(node) {
functionStack[functionStack.length - 1] += node.body.length;
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"FunctionDeclaration": startFunction,
"FunctionExpression": startFunction,
"ArrowFunctionExpression": startFunction,
"BlockStatement": countStatements,
"FunctionDeclaration:exit": endFunction,
"FunctionExpression:exit": endFunction,
"ArrowFunctionExpression:exit": endFunction
};
};
module.exports.schema = [
{
"type": "integer"
}
];

241
node_modules/eslint/lib/rules/new-cap.js generated vendored Normal file
View File

@@ -0,0 +1,241 @@
/**
* @fileoverview Rule to flag use of constructors without capital letters
* @author Nicholas C. Zakas
* @copyright 2014 Jordan Harband. All rights reserved.
* @copyright 2013-2014 Nicholas C. Zakas. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var assign = require("object-assign");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
var CAPS_ALLOWED = [
"Array",
"Boolean",
"Date",
"Error",
"Function",
"Number",
"Object",
"RegExp",
"String",
"Symbol"
];
/**
* Ensure that if the key is provided, it must be an array.
* @param {Object} obj Object to check with `key`.
* @param {string} key Object key to check on `obj`.
* @param {*} fallback If obj[key] is not present, this will be returned.
* @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback`
*/
function checkArray(obj, key, fallback) {
/* istanbul ignore if */
if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) {
throw new TypeError(key + ", if provided, must be an Array");
}
return obj[key] || fallback;
}
/**
* A reducer function to invert an array to an Object mapping the string form of the key, to `true`.
* @param {Object} map Accumulator object for the reduce.
* @param {string} key Object key to set to `true`.
* @returns {Object} Returns the updated Object for further reduction.
*/
function invert(map, key) {
map[key] = true;
return map;
}
/**
* Creates an object with the cap is new exceptions as its keys and true as their values.
* @param {Object} config Rule configuration
* @returns {Object} Object with cap is new exceptions.
*/
function calculateCapIsNewExceptions(config) {
var capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED);
if (capIsNewExceptions !== CAPS_ALLOWED) {
capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED);
}
return capIsNewExceptions.reduce(invert, {});
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var config = context.options[0] ? assign({}, context.options[0]) : {};
config.newIsCap = config.newIsCap !== false;
config.capIsNew = config.capIsNew !== false;
var skipProperties = config.properties === false;
var newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {});
var capIsNewExceptions = calculateCapIsNewExceptions(config);
var listeners = {};
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Get exact callee name from expression
* @param {ASTNode} node CallExpression or NewExpression node
* @returns {string} name
*/
function extractNameFromExpression(node) {
var name = "",
property;
if (node.callee.type === "MemberExpression") {
property = node.callee.property;
if (property.type === "Literal" && (typeof property.value === "string")) {
name = property.value;
} else if (property.type === "Identifier" && !node.callee.computed) {
name = property.name;
}
} else {
name = node.callee.name;
}
return name;
}
/**
* Returns the capitalization state of the string -
* Whether the first character is uppercase, lowercase, or non-alphabetic
* @param {string} str String
* @returns {string} capitalization state: "non-alpha", "lower", or "upper"
*/
function getCap(str) {
var firstChar = str.charAt(0);
var firstCharLower = firstChar.toLowerCase();
var firstCharUpper = firstChar.toUpperCase();
if (firstCharLower === firstCharUpper) {
// char has no uppercase variant, so it's non-alphabetic
return "non-alpha";
} else if (firstChar === firstCharLower) {
return "lower";
} else {
return "upper";
}
}
/**
* Check if capitalization is allowed for a CallExpression
* @param {Object} allowedMap Object mapping calleeName to a Boolean
* @param {ASTNode} node CallExpression node
* @param {string} calleeName Capitalized callee name from a CallExpression
* @returns {Boolean} Returns true if the callee may be capitalized
*/
function isCapAllowed(allowedMap, node, calleeName) {
if (allowedMap[calleeName] || allowedMap[context.getSource(node.callee)]) {
return true;
}
if (calleeName === "UTC" && node.callee.type === "MemberExpression") {
// allow if callee is Date.UTC
return node.callee.object.type === "Identifier" &&
node.callee.object.name === "Date";
}
return skipProperties && node.callee.type === "MemberExpression";
}
/**
* Reports the given message for the given node. The location will be the start of the property or the callee.
* @param {ASTNode} node CallExpression or NewExpression node.
* @param {string} message The message to report.
* @returns {void}
*/
function report(node, message) {
var callee = node.callee;
if (callee.type === "MemberExpression") {
callee = callee.property;
}
context.report(node, callee.loc.start, message);
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
if (config.newIsCap) {
listeners.NewExpression = function(node) {
var constructorName = extractNameFromExpression(node);
if (constructorName) {
var capitalization = getCap(constructorName);
var isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName);
if (!isAllowed) {
report(node, "A constructor name should not start with a lowercase letter.");
}
}
};
}
if (config.capIsNew) {
listeners.CallExpression = function(node) {
var calleeName = extractNameFromExpression(node);
if (calleeName) {
var capitalization = getCap(calleeName);
var isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName);
if (!isAllowed) {
report(node, "A function with a name starting with an uppercase letter should only be used as a constructor.");
}
}
};
}
return listeners;
};
module.exports.schema = [
{
"type": "object",
"properties": {
"newIsCap": {
"type": "boolean"
},
"capIsNew": {
"type": "boolean"
},
"newIsCapExceptions": {
"type": "array",
"items": {
"type": "string"
}
},
"capIsNewExceptions": {
"type": "array",
"items": {
"type": "string"
}
},
"properties": {
"type": "boolean"
}
},
"additionalProperties": false
}
];

29
node_modules/eslint/lib/rules/new-parens.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/**
* @fileoverview Rule to flag when using constructor without parentheses
* @author Ilya Volodin
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"NewExpression": function(node) {
var tokens = context.getTokens(node);
var prenticesTokens = tokens.filter(function(token) {
return token.value === "(" || token.value === ")";
});
if (prenticesTokens.length < 2) {
context.report(node, "Missing '()' invoking a constructor");
}
}
};
};
module.exports.schema = [];

176
node_modules/eslint/lib/rules/newline-after-var.js generated vendored Normal file
View File

@@ -0,0 +1,176 @@
/**
* @fileoverview Rule to check empty newline after "var" statement
* @author Gopal Venkatesan
* @copyright 2015 Gopal Venkatesan. All rights reserved.
* @copyright 2015 Casey Visco. All rights reserved.
* @copyright 2015 Ian VanSchooten. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var ALWAYS_MESSAGE = "Expected blank line after variable declarations.",
NEVER_MESSAGE = "Unexpected blank line after variable declarations.";
// Default `mode` to "always". This means that invalid options will also
// be treated as "always" and the only special case is "never"
var mode = context.options[0] === "never" ? "never" : "always";
// Cache starting and ending line numbers of comments for faster lookup
var commentEndLine = context.getAllComments().reduce(function(result, token) {
result[token.loc.start.line] = token.loc.end.line;
return result;
}, {});
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Determine if provided keyword is a variable declaration
* @private
* @param {string} keyword - keyword to test
* @returns {boolean} True if `keyword` is a type of var
*/
function isVar(keyword) {
return keyword === "var" || keyword === "let" || keyword === "const";
}
/**
* Determine if provided keyword is a variant of for specifiers
* @private
* @param {string} keyword - keyword to test
* @returns {boolean} True if `keyword` is a variant of for specifier
*/
function isForTypeSpecifier(keyword) {
return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement";
}
/**
* Determine if provided keyword is an export specifiers
* @private
* @param {string} nodeType - nodeType to test
* @returns {boolean} True if `nodeType` is an export specifier
*/
function isExportSpecifier(nodeType) {
return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" ||
nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration";
}
/**
* Determine if provided nodeType is a function specifier
* @private
* @param {string} nodeType - nodeType to test
* @returns {boolean} True if `nodeType` is a function specifier
*/
function isFunctionSpecifier(nodeType) {
return nodeType === "FunctionDeclaration" || nodeType === "FunctionExpression" ||
nodeType === "ArrowFunctionExpression";
}
/**
* Determine if provided node is the last of his parent
* @private
* @param {ASTNode} node - node to test
* @returns {boolean} True if `node` is last of his parent
*/
function isLastNode(node) {
return node.parent.body[node.parent.body.length - 1] === node;
}
/**
* Determine if a token starts more than one line after a comment ends
* @param {token} token The token being checked
* @param {integer} commentStartLine The line number on which the comment starts
* @returns {boolean} True if `token` does not start immediately after a comment
*/
function hasBlankLineAfterComment(token, commentStartLine) {
var commentEnd = commentEndLine[commentStartLine];
// If there's another comment, repeat check for blank line
if (commentEndLine[commentEnd + 1]) {
return hasBlankLineAfterComment(token, commentEnd + 1);
}
return (token.loc.start.line > commentEndLine[commentStartLine] + 1);
}
/**
* Checks that a blank line exists after a variable declaration when mode is
* set to "always", or checks that there is no blank line when mode is set
* to "never"
* @private
* @param {ASTNode} node - `VariableDeclaration` node to test
* @returns {void}
*/
function checkForBlankLine(node) {
var lastToken = context.getLastToken(node),
nextToken = context.getTokenAfter(node),
nextLineNum = lastToken.loc.end.line + 1,
noNextLineToken,
hasNextLineComment;
// Ignore if there is no following statement
if (!nextToken) {
return;
}
// Ignore if parent of node is a for variant
if (isForTypeSpecifier(node.parent.type)) {
return;
}
// Ignore if parent of node is an export specifier
if (isExportSpecifier(node.parent.type)) {
return;
}
// Some coding styles use multiple `var` statements, so do nothing if
// the next token is a `var` statement.
if (nextToken.type === "Keyword" && isVar(nextToken.value)) {
return;
}
// Ignore if it is last statement in a function
if (node.parent.parent && isFunctionSpecifier(node.parent.parent.type) && isLastNode(node)) {
return;
}
// Next statement is not a `var`...
noNextLineToken = nextToken.loc.start.line > nextLineNum;
hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined");
if (mode === "never" && noNextLineToken && !hasNextLineComment) {
context.report(node, NEVER_MESSAGE, { identifier: node.name });
}
// Token on the next line, or comment without blank line
if (
mode === "always" && (
!noNextLineToken ||
hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum)
)
) {
context.report(node, ALWAYS_MESSAGE, { identifier: node.name });
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"VariableDeclaration": checkForBlankLine
};
};
module.exports.schema = [
{
"enum": ["never", "always"]
}
];

152
node_modules/eslint/lib/rules/no-alert.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
/**
* @fileoverview Rule to flag use of alert, confirm, prompt
* @author Nicholas C. Zakas
* @copyright 2015 Mathias Schreck
* @copyright 2013 Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks if the given name is a prohibited identifier.
* @param {string} name The name to check
* @returns {boolean} Whether or not the name is prohibited.
*/
function isProhibitedIdentifier(name) {
return /^(alert|confirm|prompt)$/.test(name);
}
/**
* Reports the given node and identifier name.
* @param {RuleContext} context The ESLint rule context.
* @param {ASTNode} node The node to report on.
* @param {string} identifierName The name of the identifier.
* @returns {void}
*/
function report(context, node, identifierName) {
context.report(node, "Unexpected {{name}}.", { name: identifierName });
}
/**
* Returns the property name of a MemberExpression.
* @param {ASTNode} memberExpressionNode The MemberExpression node.
* @returns {string|undefined} Returns the property name if available, undefined else.
*/
function getPropertyName(memberExpressionNode) {
if (memberExpressionNode.computed) {
if (memberExpressionNode.property.type === "Literal") {
return memberExpressionNode.property.value;
}
} else {
return memberExpressionNode.property.name;
}
}
/**
* Finds the escope reference in the given scope.
* @param {Object} scope The scope to search.
* @param {ASTNode} node The identifier node.
* @returns {Reference|undefined} Returns the found reference or undefined if none were found.
*/
function findReference(scope, node) {
var references = scope.references.filter(function(reference) {
return reference.identifier.range[0] === node.range[0] &&
reference.identifier.range[1] === node.range[1];
});
if (references.length === 1) {
return references[0];
}
}
/**
* Checks if the given identifier name is shadowed in the given global scope.
* @param {Object} globalScope The global scope.
* @param {string} identifierName The identifier name to check
* @returns {boolean} Whether or not the name is shadowed globally.
*/
function isGloballyShadowed(globalScope, identifierName) {
var variable = globalScope.set.get(identifierName);
return Boolean(variable && variable.defs.length > 0);
}
/**
* Checks if the given identifier node is shadowed in the given scope.
* @param {Object} scope The current scope.
* @param {Object} globalScope The global scope.
* @param {string} node The identifier node to check
* @returns {boolean} Whether or not the name is shadowed.
*/
function isShadowed(scope, globalScope, node) {
var reference = findReference(scope, node),
identifierName = node.name;
if (reference) {
if (reference.resolved || isGloballyShadowed(globalScope, identifierName)) {
return true;
}
}
return false;
}
/**
* Checks if the given identifier node is a ThisExpression in the global scope or the global window property.
* @param {Object} scope The current scope.
* @param {Object} globalScope The global scope.
* @param {string} node The identifier node to check
* @returns {boolean} Whether or not the node is a reference to the global object.
*/
function isGlobalThisReferenceOrGlobalWindow(scope, globalScope, node) {
if (scope.type === "global" && node.type === "ThisExpression") {
return true;
} else if (node.name === "window") {
return !isShadowed(scope, globalScope, node);
}
return false;
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var globalScope;
return {
"Program": function() {
globalScope = context.getScope();
},
"CallExpression": function(node) {
var callee = node.callee,
identifierName,
currentScope = context.getScope();
// without window.
if (callee.type === "Identifier") {
identifierName = callee.name;
if (!isShadowed(currentScope, globalScope, callee) && isProhibitedIdentifier(callee.name)) {
report(context, node, identifierName);
}
} else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, globalScope, callee.object)) {
identifierName = getPropertyName(callee);
if (isProhibitedIdentifier(identifierName)) {
report(context, node, identifierName);
}
}
}
};
};
module.exports.schema = [];

37
node_modules/eslint/lib/rules/no-array-constructor.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
/**
* @fileoverview Disallow construction of dense arrays using the Array constructor
* @author Matt DuVall <http://www.mattduvall.com/>
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Disallow construction of dense arrays using the Array constructor
* @param {ASTNode} node node to evaluate
* @returns {void}
* @private
*/
function check(node) {
if (
node.arguments.length !== 1 &&
node.callee.type === "Identifier" &&
node.callee.name === "Array"
) {
context.report(node, "The array literal notation [] is preferrable.");
}
}
return {
"CallExpression": check,
"NewExpression": check
};
};
module.exports.schema = [];

88
node_modules/eslint/lib/rules/no-arrow-condition.js generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/**
* @fileoverview A rule to warn against using arrow functions in conditions.
* @author Jxck <https://github.com/Jxck>
* @copyright 2015 Luke Karrys. All rights reserved.
* The MIT License (MIT)
* Copyright (c) 2015 Jxck
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
"use strict";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* Checks whether or not a node is an arrow function expression.
* @param {ASTNode} node - node to test
* @returns {boolean} `true` if the node is an arrow function expression.
*/
function isArrowFunction(node) {
return node.test && node.test.type === "ArrowFunctionExpression";
}
/**
* Checks whether or not a node is a conditional expression.
* @param {ASTNode} node - node to test
* @returns {boolean} `true` if the node is a conditional expression.
*/
function isConditional(node) {
return node.body && node.body.type === "ConditionalExpression";
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Reports if a conditional statement is an arrow function.
* @param {ASTNode} node - A node to check and report.
* @returns {void}
*/
function checkCondition(node) {
if (isArrowFunction(node)) {
context.report(node, "Arrow function `=>` used inside {{statementType}} instead of comparison operator.", {statementType: node.type});
}
}
/**
* Reports if an arrow function contains an ambiguous conditional.
* @param {ASTNode} node - A node to check and report.
* @returns {void}
*/
function checkArrowFunc(node) {
if (isConditional(node)) {
context.report(node, "Arrow function used ambiguously with a conditional expression.");
}
}
return {
"IfStatement": checkCondition,
"WhileStatement": checkCondition,
"ForStatement": checkCondition,
"ConditionalExpression": checkCondition,
"ArrowFunctionExpression": checkArrowFunc
};
};
module.exports.schema = [];

57
node_modules/eslint/lib/rules/no-bitwise.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
/**
* @fileoverview Rule to flag bitwise identifiers
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var BITWISE_OPERATORS = [
"^", "|", "&", "<<", ">>", ">>>",
"^=", "|=", "&=", "<<=", ">>=", ">>>=",
"~"
];
/**
* Reports an unexpected use of a bitwise operator.
* @param {ASTNode} node Node which contains the bitwise operator.
* @returns {void}
*/
function report(node) {
context.report(node, "Unexpected use of '{{operator}}'.", { operator: node.operator });
}
/**
* Checks if the given node has a bitwise operator.
* @param {ASTNode} node The node to check.
* @returns {boolean} Whether or not the node has a bitwise operator.
*/
function hasBitwiseOperator(node) {
return BITWISE_OPERATORS.indexOf(node.operator) !== -1;
}
/**
* Report if the given node contains a bitwise operator.
* @param {ASTNode} node The node to check.
* @returns {void}
*/
function checkNodeForBitwiseOperator(node) {
if (hasBitwiseOperator(node)) {
report(node);
}
}
return {
"AssignmentExpression": checkNodeForBitwiseOperator,
"BinaryExpression": checkNodeForBitwiseOperator,
"UnaryExpression": checkNodeForBitwiseOperator
};
};
module.exports.schema = [];

29
node_modules/eslint/lib/rules/no-caller.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/**
* @fileoverview Rule to flag use of arguments.callee and arguments.caller.
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"MemberExpression": function(node) {
var objectName = node.object.name,
propertyName = node.property.name;
if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/)) {
context.report(node, "Avoid arguments.{{property}}.", { property: propertyName });
}
}
};
};
module.exports.schema = [];

47
node_modules/eslint/lib/rules/no-case-declarations.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
/**
* @fileoverview Rule to flag use of an lexical declarations inside a case clause
* @author Erik Arvidsson
* @copyright 2015 Erik Arvidsson. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Checks whether or not a node is a lexical declaration.
* @param {ASTNode} node A direct child statement of a switch case.
* @returns {boolean} Whether or not the node is a lexical declaration.
*/
function isLexicalDeclaration(node) {
switch (node.type) {
case "FunctionDeclaration":
case "ClassDeclaration":
return true;
case "VariableDeclaration":
return node.kind !== "var";
default:
return false;
}
}
return {
"SwitchCase": function(node) {
for (var i = 0; i < node.consequent.length; i++) {
var statement = node.consequent[i];
if (isLexicalDeclaration(statement)) {
context.report({
node: node,
message: "Unexpected lexical declaration in case block."
});
}
}
}
};
};
module.exports.schema = [];

58
node_modules/eslint/lib/rules/no-catch-shadow.js generated vendored Normal file
View File

@@ -0,0 +1,58 @@
/**
* @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier
* @author Ian Christian Myers
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Check if the parameters are been shadowed
* @param {object} scope current scope
* @param {string} name parameter name
* @returns {boolean} True is its been shadowed
*/
function paramIsShadowing(scope, name) {
return astUtils.getVariableByName(scope, name) !== null;
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"CatchClause": function(node) {
var scope = context.getScope();
// When blockBindings is enabled, CatchClause creates its own scope
// so start from one upper scope to exclude the current node
if (scope.block === node) {
scope = scope.upper;
}
if (paramIsShadowing(scope, node.param.name)) {
context.report(node, "Value of '{{name}}' may be overwritten in IE 8 and earlier.",
{ name: node.param.name });
}
}
};
};
module.exports.schema = [];

48
node_modules/eslint/lib/rules/no-class-assign.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
/**
* @fileoverview A rule to disallow modifying variables of class declarations
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Finds and reports references that are non initializer and writable.
* @param {Variable} variable - A variable to check.
* @returns {void}
*/
function checkVariable(variable) {
astUtils.getModifyingReferences(variable.references).forEach(function(reference) {
context.report(
reference.identifier,
"`{{name}}` is a class.",
{name: reference.identifier.name});
});
}
/**
* Finds and reports references that are non initializer and writable.
* @param {ASTNode} node - A ClassDeclaration/ClassExpression node to check.
* @returns {void}
*/
function checkForClass(node) {
context.getDeclaredVariables(node).forEach(checkVariable);
}
return {
"ClassDeclaration": checkForClass,
"ClassExpression": checkForClass
};
};
module.exports.schema = [];

133
node_modules/eslint/lib/rules/no-cond-assign.js generated vendored Normal file
View File

@@ -0,0 +1,133 @@
/**
* @fileoverview Rule to flag assignment in a conditional statement's test expression
* @author Stephen Murray <spmurrayzzz>
*/
"use strict";
var NODE_DESCRIPTIONS = {
"DoWhileStatement": "a 'do...while' statement",
"ForStatement": "a 'for' statement",
"IfStatement": "an 'if' statement",
"WhileStatement": "a 'while' statement"
};
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var prohibitAssign = (context.options[0] || "except-parens");
/**
* Check whether an AST node is the test expression for a conditional statement.
* @param {!Object} node The node to test.
* @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`.
*/
function isConditionalTestExpression(node) {
return node.parent &&
node.parent.test &&
node === node.parent.test;
}
/**
* Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement.
* @param {!Object} node The node to use at the start of the search.
* @returns {?Object} The closest ancestor node that represents a conditional statement.
*/
function findConditionalAncestor(node) {
var currentAncestor = node;
do {
if (isConditionalTestExpression(currentAncestor)) {
return currentAncestor.parent;
}
} while ((currentAncestor = currentAncestor.parent));
return null;
}
/**
* Check whether the code represented by an AST node is enclosed in parentheses.
* @param {!Object} node The node to test.
* @returns {boolean} `true` if the code is enclosed in parentheses; otherwise, `false`.
*/
function isParenthesised(node) {
var previousToken = context.getTokenBefore(node),
nextToken = context.getTokenAfter(node);
return previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
nextToken.value === ")" && nextToken.range[0] >= node.range[1];
}
/**
* Check whether the code represented by an AST node is enclosed in two sets of parentheses.
* @param {!Object} node The node to test.
* @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`.
*/
function isParenthesisedTwice(node) {
var previousToken = context.getTokenBefore(node, 1),
nextToken = context.getTokenAfter(node, 1);
return isParenthesised(node) &&
previousToken.value === "(" && previousToken.range[1] <= node.range[0] &&
nextToken.value === ")" && nextToken.range[0] >= node.range[1];
}
/**
* Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses.
* @param {!Object} node The node for the conditional statement.
* @returns {void}
*/
function testForAssign(node) {
if (node.test &&
(node.test.type === "AssignmentExpression") &&
(node.type === "ForStatement" ?
!isParenthesised(node.test) :
!isParenthesisedTwice(node.test)
)
) {
// must match JSHint's error message
context.report({
node: node,
loc: node.test.loc.start,
message: "Expected a conditional expression and instead saw an assignment."
});
}
}
/**
* Check whether an assignment expression is descended from a conditional statement's test expression.
* @param {!Object} node The node for the assignment expression.
* @returns {void}
*/
function testForConditionalAncestor(node) {
var ancestor = findConditionalAncestor(node);
if (ancestor) {
context.report(ancestor, "Unexpected assignment within {{type}}.", {
type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type
});
}
}
if (prohibitAssign === "always") {
return {
"AssignmentExpression": testForConditionalAncestor
};
}
return {
"DoWhileStatement": testForAssign,
"ForStatement": testForAssign,
"IfStatement": testForAssign,
"WhileStatement": testForAssign
};
};
module.exports.schema = [
{
"enum": ["except-parens", "always"]
}
];

27
node_modules/eslint/lib/rules/no-console.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* @fileoverview Rule to flag use of console object
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"MemberExpression": function(node) {
if (node.object.name === "console") {
context.report(node, "Unexpected console statement.");
}
}
};
};
module.exports.schema = [];

41
node_modules/eslint/lib/rules/no-const-assign.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
/**
* @fileoverview A rule to disallow modifying variables that are declared using `const`
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/
"use strict";
var astUtils = require("../ast-utils");
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Finds and reports references that are non initializer and writable.
* @param {Variable} variable - A variable to check.
* @returns {void}
*/
function checkVariable(variable) {
astUtils.getModifyingReferences(variable.references).forEach(function(reference) {
context.report(
reference.identifier,
"`{{name}}` is constant.",
{name: reference.identifier.name});
});
}
return {
"VariableDeclaration": function(node) {
if (node.kind === "const") {
context.getDeclaredVariables(node).forEach(checkVariable);
}
}
};
};
module.exports.schema = [];

73
node_modules/eslint/lib/rules/no-constant-condition.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
/**
* @fileoverview Rule to flag use constant conditions
* @author Christian Schulz <http://rndm.de>
* @copyright 2014 Christian Schulz. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Checks if a node has a constant truthiness value.
* @param {ASTNode} node The AST node to check.
* @returns {Bool} true when node's truthiness is constant
* @private
*/
function isConstant(node) {
switch (node.type) {
case "Literal":
case "ArrowFunctionExpression":
case "FunctionExpression":
case "ObjectExpression":
case "ArrayExpression":
return true;
case "UnaryExpression":
return isConstant(node.argument);
case "BinaryExpression":
case "LogicalExpression":
return isConstant(node.left) && isConstant(node.right);
case "AssignmentExpression":
return (node.operator === "=") && isConstant(node.right);
case "SequenceExpression":
return isConstant(node.expressions[node.expressions.length - 1]);
// no default
}
return false;
}
/**
* Reports when the given node contains a constant condition.
* @param {ASTNode} node The AST node to check.
* @returns {void}
* @private
*/
function checkConstantCondition(node) {
if (node.test && isConstant(node.test)) {
context.report(node, "Unexpected constant condition.");
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
return {
"ConditionalExpression": checkConstantCondition,
"IfStatement": checkConstantCondition,
"WhileStatement": checkConstantCondition,
"DoWhileStatement": checkConstantCondition,
"ForStatement": checkConstantCondition
};
};
module.exports.schema = [];

23
node_modules/eslint/lib/rules/no-continue.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
/**
* @fileoverview Rule to flag use of continue statement
* @author Borislav Zhivkov
* @copyright 2015 Borislav Zhivkov. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"ContinueStatement": function(node) {
context.report(node, "Unexpected use of continue statement");
}
};
};
module.exports.schema = [];

64
node_modules/eslint/lib/rules/no-control-regex.js generated vendored Normal file
View File

@@ -0,0 +1,64 @@
/**
* @fileoverview Rule to forbid control charactes from regular expressions.
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
/**
* Get the regex expression
* @param {ASTNode} node node to evaluate
* @returns {*} Regex if found else null
* @private
*/
function getRegExp(node) {
if (node.value instanceof RegExp) {
return node.value;
} else if (typeof node.value === "string") {
var parent = context.getAncestors().pop();
if ((parent.type === "NewExpression" || parent.type === "CallExpression") &&
parent.callee.type === "Identifier" && parent.callee.name === "RegExp") {
// there could be an invalid regular expression string
try {
return new RegExp(node.value);
} catch (ex) {
return null;
}
}
} else {
return null;
}
}
return {
"Literal": function(node) {
var computedValue,
regex = getRegExp(node);
if (regex) {
computedValue = regex.toString();
if (/[\x00-\x1f]/.test(computedValue)) {
context.report(node, "Unexpected control character in regular expression.");
}
}
}
};
};
module.exports.schema = [];

22
node_modules/eslint/lib/rules/no-debugger.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
/**
* @fileoverview Rule to flag use of a debugger statement
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"DebuggerStatement": function(node) {
context.report(node, "Unexpected 'debugger' statement.");
}
};
};
module.exports.schema = [];

25
node_modules/eslint/lib/rules/no-delete-var.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/**
* @fileoverview Rule to flag when deleting variables
* @author Ilya Volodin
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"UnaryExpression": function(node) {
if (node.operator === "delete" && node.argument.type === "Identifier") {
context.report(node, "Variables should not be deleted.");
}
}
};
};
module.exports.schema = [];

27
node_modules/eslint/lib/rules/no-div-regex.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* @fileoverview Rule to check for ambiguous div operator in regexes
* @author Matt DuVall <http://www.mattduvall.com>
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
return {
"Literal": function(node) {
var token = context.getFirstToken(node);
if (token.type === "RegularExpression" && token.value[1] === "=") {
context.report(node, "A regular expression literal can be confused with '/='.");
}
}
};
};
module.exports.schema = [];

73
node_modules/eslint/lib/rules/no-dupe-args.js generated vendored Normal file
View File

@@ -0,0 +1,73 @@
/**
* @fileoverview Rule to flag duplicate arguments
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
* @copyright 2015 Toru Nagashima. All rights reserved.
* See LICENSE file in root directory for full license.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Checks whether or not a given definition is a parameter's.
* @param {escope.DefEntry} def - A definition to check.
* @returns {boolean} `true` if the definition is a parameter's.
*/
function isParameter(def) {
return def.type === "Parameter";
}
/**
* Determines if a given node has duplicate parameters.
* @param {ASTNode} node The node to check.
* @returns {void}
* @private
*/
function checkParams(node) {
var variables = context.getDeclaredVariables(node);
var keyMap = Object.create(null);
for (var i = 0; i < variables.length; ++i) {
var variable = variables[i];
// TODO(nagashima): Remove this duplication check after https://github.com/estools/escope/pull/79
var key = "$" + variable.name; // to avoid __proto__.
if (!isParameter(variable.defs[0]) || keyMap[key]) {
continue;
}
keyMap[key] = true;
// Checks and reports duplications.
var defs = variable.defs.filter(isParameter);
if (defs.length >= 2) {
context.report({
node: node,
message: "Duplicate param '{{name}}'.",
data: {name: variable.name}
});
}
}
}
//--------------------------------------------------------------------------
// Public API
//--------------------------------------------------------------------------
return {
"FunctionDeclaration": checkParams,
"FunctionExpression": checkParams
};
};
module.exports.schema = [];

82
node_modules/eslint/lib/rules/no-dupe-class-members.js generated vendored Normal file
View File

@@ -0,0 +1,82 @@
/**
* @fileoverview A rule to disallow duplicate name in class members.
* @author Toru Nagashima
* @copyright 2015 Toru Nagashima. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var stack = [];
/**
* Gets state of a given member name.
* @param {string} name - A name of a member.
* @param {boolean} isStatic - A flag which specifies that is a static member.
* @returns {object} A state of a given member name.
* - retv.init {boolean} A flag which shows the name is declared as normal member.
* - retv.get {boolean} A flag which shows the name is declared as getter.
* - retv.set {boolean} A flag which shows the name is declared as setter.
*/
function getState(name, isStatic) {
var stateMap = stack[stack.length - 1];
var key = "$" + name; // to avoid "__proto__".
if (!stateMap[key]) {
stateMap[key] = {
nonStatic: {init: false, get: false, set: false},
static: {init: false, get: false, set: false}
};
}
return stateMap[key][isStatic ? "static" : "nonStatic"];
}
return {
// Initializes the stack of state of member declarations.
"Program": function() {
stack = [];
},
// Initializes state of member declarations for the class.
"ClassBody": function() {
stack.push(Object.create(null));
},
// Disposes the state for the class.
"ClassBody:exit": function() {
stack.pop();
},
// Reports the node if its name has been declared already.
"MethodDefinition": function(node) {
if (node.computed) {
return;
}
var name = node.key.name;
var state = getState(name, node.static);
var isDuplicate = false;
if (node.kind === "get") {
isDuplicate = (state.init || state.get);
state.get = true;
} else if (node.kind === "set") {
isDuplicate = (state.init || state.set);
state.set = true;
} else {
isDuplicate = (state.init || state.get || state.set);
state.init = true;
}
if (isDuplicate) {
context.report(node, "Duplicate name \"{{name}}\".", {name: name});
}
}
};
};
module.exports.schema = [];

Some files were not shown because too many files have changed in this diff Show More