eslint / espree Goto Github PK
View Code? Open in Web Editor NEWMonorepo for the JS language tools.
License: BSD 2-Clause "Simplified" License
Monorepo for the JS language tools.
License: BSD 2-Clause "Simplified" License
Support unicode escapes of any number of characters. ex: \u{0}
, \u{abcdef123456789}
Per ESTree: Program nodes now will have sourceType
property of module
or `script'.
See mikesherov/esprima@e7f1d03
as defined in: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components the note says:
A conforming implementation must not use the extended definition of EscapeSequence described in B.1.2 when parsing a TemplateCharacter.
Espree is currently using the old mark()
and markEnd()
methods to track location (from Esprima 1.2.2). Esprima Harmony has two new methods markerCreate()
and markerApply()
. Before we can merge over more complex features, we need to switch location tracking to what's in Harmony.
We need a website to post Espree documentation and a demo. It would be nice if it had the same visual language as the eslint.org, but I don't think that's 100% necessary.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Espree parser fails on the following with Unexpected token *
:
class Foo {
*bar() {
}
}
Test case:
var espree = require("espree");
espree.parse('class Foo {*bar() {}}', {
"ecmaFeatures": {
"classes": true,
"generators": true,
"objectLiteralShorthandMethods": true,
},
});
Stack:
node_modules/espree/espree.js:5373
throw e;
^
Error: Line 1: Unexpected token *
at throwError (node_modules/espree/espree.js:2078:17)
at throwUnexpected (node_modules/espree/espree.js:2141:5)
at parseObjectPropertyKey (node_modules/espree/espree.js:2364:5)
at parseClassBody (node_modules/espree/espree.js:4934:15)
at parseClassDeclaration (node_modules/espree/espree.js:5023:17)
at parseSourceElement (node_modules/espree/espree.js:5053:28)
at parseSourceElements (node_modules/espree/espree.js:5101:25)
at parseProgram (node_modules/espree/espree.js:5120:12)
at Object.parse (node_modules/espree/espree.js:5361:19)
at Object.<anonymous> (esp.js:3:8)
See eslint/eslint#1990.
Phase 1 is all about setting up the repository in such a way that it's easier to make changes later on.
lib/
undefined
instead of null
create-test-.js
improperly changes undefined
array members to null
.Recently when working on defaultParams
and destructuring
I noticed that I was having some mismatches with Esprima on the expected output, especially involving the placeholder when there are not defaults specified for each parameter.
When I use create-test
to generate the expected output it seems to show [null, 1]
for function(a, b=1){}
, but when i actually console.log
the output from Esprima, it looks like [undefined, 1]
.
Here is I think the source of the issue:
The only thing that makes me unsure is that the single test in esprima also shows null
as the placeholder, but I can only assume they're using JSON.stringify in their tests, because Esprima will not generate that output:
https://github.com/jquery/esprima/blob/harmony/test/harmonytest.js#L2612
Let me know if you have any ideas otherwise I'll like manually change the tests to use undefined
as part of #51, which changed some of the code around this area and caused me to bump into this issue.
Those statements should be valid:
var a = [...b, 1];
foo(...a, b, ...c);
Right now, running eslint on code like this gives me error Spread must be the final element of an element list
and as it is a syntax error, it does not lint the file.
See MDN
Refs #10. Esprima harmony
already supports this.
Perhaps this is intentional, but the range given to object literal shorthand generator methods includes only the method body {}
. Since they key is part of the parent property and overlapping, non-ancestral ranges might get confusing, I'm not sure that the FunctionExpression
's range should include all of *foo(arg1) {}
, but it seems like the range should expand to at least (arg1) {}
.
Related: eslint/eslint#1677
//test.js
var inspect = require('util').inspect,
espree = require('espree');
var source = [
"({",
" *foo(arg1) {}",
"})"
].join("\n");
var ast = espree.parse(source, {
range: true,
tokens: true,
ecmaFeatures: {
generators: true,
objectLiteralShorthandMethods: true
}
});
console.log(inspect(ast.body[0].expression.properties[0]));
console.log(inspect(ast.body[0].expression.properties[0].value.params[0]));
console.log(inspect(ast.tokens));
$ node test.js
{ type: 'Property',
key: { type: 'Identifier', name: 'foo', range: [ 8, 11 ] },
value:
{ type: 'FunctionExpression',
id: null,
params: [ [Object] ],
defaults: [],
body: { type: 'BlockStatement', body: [], range: [Object] },
rest: null,
generator: true,
expression: false,
range: [ 18, 20 ] },
kind: 'init',
method: true,
shorthand: false,
computed: false,
range: [ 7, 20 ] }
{ type: 'Identifier', name: 'arg1', range: [ 12, 16 ] }
[ { type: 'Punctuator', value: '(', range: [ 0, 1 ] },
{ type: 'Punctuator', value: '{', range: [ 1, 2 ] },
{ type: 'Punctuator', value: '*', range: [ 7, 8 ] },
{ type: 'Identifier', value: 'foo', range: [ 8, 11 ] },
{ type: 'Punctuator', value: '(', range: [ 11, 12 ] },
{ type: 'Identifier', value: 'arg1', range: [ 12, 16 ] },
{ type: 'Punctuator', value: ')', range: [ 16, 17 ] },
{ type: 'Punctuator', value: '{', range: [ 18, 19 ] },
{ type: 'Punctuator', value: '}', range: [ 19, 20 ] },
{ type: 'Punctuator', value: '}', range: [ 21, 22 ] },
{ type: 'Punctuator', value: ')', range: [ 22, 23 ] } ]
Edit: Add arg1
to output.
@mikesherov further improved upon what we have for Esprima, so best to port those changes in:
sourceType="module"
effectible enables strict mode (e.g.: WithStatement
is invalid in modules)ImportDeclaration
and ExportDeclaration
cannot be used inside functions (missing tests and implementation)This repository README states: "Espree starts as a fork of Esprima v1.2.2". However, all of history of Esprima up to this point have been conflated into one initial commit. It seems it would be more fair to Esprima contributors to preserve the history.
For Node.js compatibility, it would be good to add the option to use return
in the global scope.
Working on this now.
Trying to wrap my head around the extra
object, which seems to be used everywhere for everything. Is it just a combination of parsing options & parsing state?
Ref estree/estree#1:
interface TryStatement <: Statement {
// ....
handler: CatchClause | null;
handlers: [ CatchClause ]; // Removed
// ....
}
The handlers
array on TryStatement
nodes was replaced with a single handler
, which may be either a CatchClause
or null
.
#70 added support for the singular handler
property. The next step is to remove handlers
. This will be a breaking change.
Currently it is parsed as an expression with an AssignmentPattern in it.
We need a nice logo to represent Espree on the interwebs. Any and all help welcome.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
Currently, for
loops (for
, for-in
, for-of
) all allow let
to be used even when blockBindings
is set to false. So this works fine:
for (let x of y) {
}
With this config:
{
blockBindings: false,
forOf: true
}
This should throw an error instead.
As I know, espree is a fork of Esprima with improvements of es6 support, so Esprima 2.0 is out with a bunch of es6 improvements, look it (Also it was moved to jquery org. https://github.com/jquery/esprima/)
The way that template string tokens are generated is pretty strange. This code:
var foo = `hi${bar}`;
Is tokenized as:
[
{
"type": "Keyword",
"value": "var"
},
{
"type": "Identifier",
"value": "foo"
},
{
"type": "Punctuator",
"value": "="
},
{
"value": "`hi${"
},
{
"type": "Identifier",
"value": "bar"
},
{
"type": "Punctuator",
"value": "}"
},
{
"type": "Punctuator",
"value": ";"
}
]
So the first part of the template string is represented by a token without a type, and then the rest are just regular tokens, completely losing the end of the template string.
In the README you say you're going to break the code base down into smaller files in a CommonJS pattern. Would it be possible to make it so that features are not dependent on one another. So say you don't care about parsing comments the comment module doesn't need to get loaded or included.
Thinking about this because I have a library where I want to use Esprima (or any proper code parser) instead of hacky regular expressions but the size of the libraries are just too large. Being able to shrink it down to just what I need could solve my issue.
Espree is missing the lib/ directory in the npm package.
Add support for JSX syntax. This should be done in the same form as esprima-fb
.
Enable forOf
{ forOf: true }
Espree will error with "undefined"
for (var k in console) {
doSomething();
}
See test files in PR for examples.
The following should be legal but throws an error when objectLiteralShorthandMethods
is enabled:
var x = {
"foo"() {
return bar;
}
};
For Unicode code point escapes, the string values are still valid JavaScript regardless of the feature state. But the test runner is hard-coded to check for a thrown error if the features is set to off. Thus, I'm unable to write passing tests for this feature.
A few ideas:
@nzakas thoughts?
I noticed that ReturnStatement
nodes doesn’t have leadingComments
and trailingComments
attached in some cases.
The following code example fails and doen’t have leadingComments
or trailingComments
:
function a() {
/* before */
return;
/* after */
}
The following code examples work:
Without ReturnStatement
:
function a() {
/* before */
b();
/* after */
}
Only one leading comment:
function a() {
/* before */
return;
}
Only one trailing comment:
function a() {
return;
/* after */
}
Same problem with the debugger
statement.
Esprima bug: https://code.google.com/p/esprima/issues/detail?id=609
This is a regression from espree 0.12.0.
var espree = require('espree');
espree.parse('<foo bar={`${baz}`} />', {
ecmaFeatures: {
templateStrings: true,
jsx: true
}
});
// Raises: Unexpected token ILLEGAL
The same code without ${baz}
is OK
Given the following example:
a()
gives the following loc
for the Programm
AST node:
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 3
}
}
if you have an extra line break
a()
you get the following loc
:
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 2,
"column": 0
}
}
Each extra line will increase loc.end.line
a()
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 8,
"column": 0
}
}
But if you use a semicolon after the CallExpression
you will get a different loc
for Program
even if you have multiple empty lines:
a();
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 4
}
}
While support for destructuring was added in #51 none of these cases work:
function a({x = 10}) {}
function a({x = 10, y: { z = 10 }}) {}
({x = 10}) => x
({x = 10, y: { z = 10 }}) => [x,y]
[a=10] = 0
var {a = 10} = {}
Latest spec can be found here:
estree/estree#13
From eslint/eslint#1805
Maybe a bug with ES 6 block bindings?
$ eslint -v
v0.14.1
$ eslint -c .eslintrc test.js
test.js
4:7 error Unexpected token const
✖ 1 problem (1 error, 0 warnings)
$ cat test.js
function fn(foo) {
switch (foo) {
case "foo":
const bar = "bar";
break;
}
}
$ cat .eslintrc
env:
browser: true,
node: true
ecmaFeatures:
blockBindings: true
Want to back this issue? Place a bounty on it! We accept bounties via Bountysource.
For this case:
export default function() {}
The function should be represented with a FunctionDeclaration
node with null id
, but is currently represented by a FunctionExpression
node.
Using espree master, this code :
espree.parse('class A { set foo(){} }', { ecmaFeatures: { classes: true }});
Throws :
Error: ASSERT: Message reference must be in range
at assert (/home/ubuntu/workspace/espree.js:78:15)
at /home/ubuntu/workspace/espree.js:2083:17
at String.replace (native)
at throwError (/home/ubuntu/workspace/espree.js:2080:29)
at throwErrorTolerant (/home/ubuntu/workspace/espree.js:2106:20)
at tryParseMethodDefinition (/home/ubuntu/workspace/espree.js:2438:17)
at parseClassBody (/home/ubuntu/workspace/espree.js:4984:22)
at parseClassDeclaration (/home/ubuntu/workspace/espree.js:5065:17)
at parseSourceElement (/home/ubuntu/workspace/espree.js:5095:28)
at parseSourceElements (/home/ubuntu/workspace/espree.js:5143:25)
I think tryParseMethodDefinition
L2438 should be throwErrorTolerant(lookahead, Messages.UnexpectedToken, lookahead.value);
So, this happened:
http://blog.jquery.com/2015/01/26/jquery-foundation-adopts-esprima/
How does this affect the Espree project? Are pull requests against Esprima more likely to be merged? Is it worth reaching out to the Esprima project to try to coordinate a merge?
Is Espree to Esprima as io.js is to node.js?
Here are a few ES6-based projects to consider adding to the 3rd party dir once we get module support:
https://github.com/facebook/immutable-js
https://github.com/emberjs/ember.js
https://github.com/babel/babel
So excited this is landing soon!
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
This feature allows an extra ecmascript
option to be passed to the parse()
method. This determines the syntax will be accepted by the parser. The default is all syntax (similar to Esprima) and the valid values are currently 5 and 6.
To test, it's easiest to use let
and const
. Espree already parses them but technically these are not allowed in ECMAScript 5. So when ecmascript
is 5, using let
and const
should throw an error.
Right now, I need to enable classes
and superInFunctions
in order to use super()
in a class. Classes should always be allowed to use super
regardless of the superInFunctions
flag.
Right now, enabling ecmaFeatures.modules
means that classes can be default exported:
export default class Foo {}
This should throw an error if ecmaFeatures.classes
is false.
var espree = require('espree');
espree.parse('var a = {get};', {
ecmaFeatures: {
objectLiteralShorthandProperties: true
}
});
Raises Error: Line 1: Unexpected token }
Rename get
to anything else, and it works.
Like the title says, wouldn't it be good to contribute to esprima-fb?
Or are there any reasons why you can't do this?
Ref estree/estree#1:
interface TryStatement <: Statement {
// ....
handler: CatchClause | null;
handlers: [ CatchClause ]; // Removed
// ....
}
The handlers
array on TryStatement
nodes was replaced with a single handler
, which may be either a CatchClause
or null
.
Presumably the best way to do this is to port jquery/esprima#1034, a backward-compatible change which adds handler
and preserves handlers
, then remove handlers
as a breaking change later?
This is a rollup that will let us keep track of ES6 progress.
let
declarationsconst
declarationsu
flagy
flagsuper
referencesfor-of
loops__proto__
)Esprima incorrectly implemented ClassDeclaration and ClassExpression, and since I copied that, we have the same problem. The issue is that ESTree specified the name of a class as id
while we are using name
. So, we need to switch to use id
instead.
Rest parameters should now end up in a RestElement
in a function's params
array (see https://github.com/estree/estree/blob/master/es6.md#restelement). This would involve removing the rest
property from all function types and would be a breaking change.
Given the following snippet, with ESLint I get an error on the catch
line with Unexpected token {
function x({a}) {
try {
const {b} = a;
}
catch({stack}) {
}
}
The following example crashes eslint (caused by the last line in the file):
var left, aSize, bSize;
aSize = {
width: 800,
height: 600
};
bSize = {
width: 200,
height: 100
};
left = (aSize.width/2) - ()
with error
eslint test.js
/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/token-store.js:181
starts[right.range[0]] + padding
^
TypeError: Cannot read property '0' of undefined
at EventEmitter.api.getTokensBetween (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/token-store.js:181:31)
at RuleContext.(anonymous function) [as getTokensBetween] (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/rule-context.js:82:33)
at isSpaced (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/rules/space-infix-ops.js:21:34)
at EventEmitter.checkBinary (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/rules/space-infix-ops.js:40:14)
at EventEmitter.emit (events.js:117:20)
at Controller.controller.traverse.enter (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/eslint.js:673:25)
at Controller.__execute (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/node_modules/estraverse/estraverse.js:397:31)
at Controller.traverse (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/node_modules/estraverse/estraverse.js:495:28)
at EventEmitter.module.exports.api.verify (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/eslint.js:666:24)
at processFile (/home/julien/.nvm/v0.10.30/lib/node_modules/eslint/lib/cli-engine.js:172:27)
Looks like parentheses in the end of the line left = (aSize.width / 2) - ()
treated as ArrowParameterPlaceHolder
https://www.dropbox.com/s/0oltkd0vbdo0iew/Screenshot%202015-02-10%2018.51.52.png?dl=0
ECMAScript 6 adds two extra flags to regular expressions, u
and y
. We should be able to add those as valid options in ES6 and edge modes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.