flow-parser
Advanced tools
Comparing version 0.5.0 to 0.6.0
{ | ||
"name": "flow-parser", | ||
"version": "0.5.0", | ||
"version": "0.6.0", | ||
"description": "JavaScript parser written in OCaml. Produces SpiderMonkey AST", | ||
@@ -29,5 +29,5 @@ "author": { | ||
"scripts": { | ||
"test": "node test/run_esprima_tests.js; node test/run_hardcoded_tests.js", | ||
"test": "bash test/run_all.sh", | ||
"prepublish": "make js" | ||
} | ||
} |
@@ -1,33 +0,37 @@ | ||
# The Flow Parser | ||
# The flow-parser package | ||
The Flow Parser is a JavaScript parser written in OCaml. It produces an AST that conforms to [SpiderMonkey's Parser API](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API) and that mostly matches what [esprima](http://esprima.org/) produces. The Flow Parser can be compiled to native code or can be compiled to JavaScript using [js_of_ocaml](http://ocsigen.org/js_of_ocaml/). | ||
This package contains the Flow parser in its compiled-to-JavaScript form. | ||
## Building the Flow Parser | ||
# What is Flow | ||
Building the Flow Parser requires OCaml. Compiling to JavaScript requires js_of_ocaml. | ||
See [flowtype.org](http://flowtype.org/). The code for the Flow parser [lives on GitHub](https://github.com/facebook/flow/tree/master/src/parser). | ||
### Initial set up | ||
# What is the Flow Parser | ||
* [Install opam](https://opam.ocaml.org/doc/Install.html) | ||
* `opam install js_of_ocaml` | ||
The Flow Parser is a JavaScript parser written in OCaml. It produces an AST that conforms to the [ESTree spec](https://github.com/estree/estree) and that mostly matches what [esprima](http://esprima.org/) produces. The Flow Parser can be compiled to native code or can be compiled to JavaScript using [js_of_ocaml](http://ocsigen.org/js_of_ocaml/). This npm package contains the Flow parser compiled to JavaScript. | ||
### Building the OCaml Flow Parser library | ||
# Usage | ||
make | ||
### Compiling the Flow Parser to JavaScript | ||
You can use the Flow parser in your browser or in node. To use in node you can just do | ||
make js | ||
```JavaScript | ||
require('flow-parser').parse('1+1'); | ||
``` | ||
## Tests | ||
To use in the browser, you can add | ||
The Flow Parser's test suite tests the JavaScript version of the parser, so you will need js_of_ocaml installed. The tests and tools also have some node module dependencies, so you will need to run | ||
```HTML | ||
<script src="flow_parser.js"></script> | ||
``` | ||
### Initial set up | ||
which will make the `flow` object available to use like so: | ||
* Follow the steps in [Building the Flow Parser](https://github.com/facebook/flow/blob/master/src/parser/README.md#building-the-flow-parser) | ||
* `npm install` | ||
```JavaScript | ||
flow.parse('1+1'); | ||
``` | ||
### Running the Tests | ||
# bin scripts | ||
make test | ||
* `flowparse` - Pass it a string to parse or a file to parse and it dumps the AST to stdout | ||
* `flowvalidate` - Pass it one or more files and it checks if they parse | ||
@@ -205,2 +205,6 @@ /** | ||
break; | ||
case 'ArrowFunctionExpression': | ||
esprima.returnType = null; | ||
esprima.typeParameters = null; | ||
break; | ||
} | ||
@@ -211,3 +215,3 @@ | ||
case 'FunctionExpression': | ||
case 'ArrowFunction': | ||
case 'ArrowFunctionExpression': | ||
if (Array.isArray(esprima.defaults)) { | ||
@@ -220,2 +224,5 @@ for (var i = 0; i < esprima.defaults.length; i++) { | ||
} | ||
if (esprima.async === undefined) { | ||
esprima.async = false; | ||
} | ||
} | ||
@@ -222,0 +229,0 @@ |
@@ -1602,3 +1602,51 @@ module.exports = { | ||
}, | ||
'(x: number): number => x': { | ||
'body.0.expression': { | ||
'params': [ | ||
{ | ||
'name': 'x', | ||
'typeAnnotation.typeAnnotation.type': 'NumberTypeAnnotation', | ||
}, | ||
], | ||
'returnType.typeAnnotation.type': 'NumberTypeAnnotation', | ||
}, | ||
}, | ||
'<T>(x: T): T => x': { | ||
'body.0.expression.typeParameters.params': [ | ||
{ | ||
'name': 'T', | ||
} | ||
], | ||
}, | ||
}, | ||
'Invalid Arrow Functions': { | ||
'var f = x: number => 42': { | ||
'errors': { | ||
'0.message': 'Unexpected token :', | ||
} | ||
}, | ||
'label: typeThatIsActuallyAnParam => 42': { | ||
'body': [ | ||
{ | ||
'type': 'LabeledStatement', | ||
'body.expression.type': 'ArrowFunctionExpression', | ||
}, | ||
], | ||
}, | ||
'<T>x => 42': { | ||
'errors': { | ||
'0.message': 'Unexpected token ILLEGAL', | ||
}, | ||
}, | ||
'*x => x': { | ||
'errors': { | ||
'0.message': 'Unexpected token *', | ||
}, | ||
}, | ||
'*(x) => x': { | ||
'errors': { | ||
'0.message': 'Unexpected token *', | ||
}, | ||
}, | ||
}, | ||
'Declare Module': { | ||
@@ -1939,6 +1987,140 @@ 'declare module A {}': { | ||
'errors': { | ||
'0.message': 'Rest parameter must be final parameter of an argument list', | ||
'0.message': 'Unexpected token ...', | ||
} | ||
}, | ||
}, | ||
'Invalid For Of Loops': { | ||
'for (var x = 42 of list) process(x);': { | ||
'errors': { | ||
'0.message': 'Invalid left-hand side in for-of', | ||
}, | ||
}, | ||
}, | ||
'Async/Await': { | ||
'async: while (async) { continue async; }': {}, | ||
'await: while (await) { continue await; }': {}, | ||
'var await = { await }': {}, | ||
'var async = { async }': {}, | ||
'var async = { async : foo }': {}, | ||
'async function f() { var await = { await : async function foo() {} } }': | ||
{}, | ||
'async function f(async, await) { var x = await async; return x; }': {}, | ||
'function f() { return await; }': {}, | ||
'async function f() { return await; }': { | ||
'errors': { | ||
// inside an async function, await is considered a keyword | ||
'0.message': 'Unexpected token ;', | ||
}, | ||
}, | ||
'function f(x: async) : async { return x; }': {}, | ||
'declare async function foo() : T': { | ||
'errors': { | ||
'0.message': "async is an implementation detail and isn't necessary " + | ||
"for your declare function statement. It is sufficient for your " + | ||
"declare function to just have a Promise return type.", | ||
}, | ||
}, | ||
'declare async function async(async : async) : async': { | ||
'errors': { | ||
'0.message': "async is an implementation detail and isn't necessary " + | ||
"for your declare function statement. It is sufficient for your " + | ||
"declare function to just have a Promise return type.", | ||
}, | ||
}, | ||
'declare async function await(await : await) : await': { | ||
'errors': { | ||
'0.message': "async is an implementation detail and isn't necessary " + | ||
"for your declare function statement. It is sufficient for your " + | ||
"declare function to just have a Promise return type.", | ||
}, | ||
}, | ||
'declare function foo() : Promise<async>': {}, | ||
'declare function foo() : Promise<await>': {}, | ||
'declare function async() : bar': {}, | ||
'async function foo() { var await = 4; }': {}, | ||
'async function foo() { var await = 4; return await; }': { | ||
'errors': { | ||
'0.message': 'Unexpected token ;', | ||
}, | ||
}, | ||
// esprima chokes on these | ||
'export const async = 5': {}, | ||
'export const await = 5': {}, | ||
'export const foo = async function() { }': {}, | ||
'export const foo = async () => y': {}, | ||
'export function async() { }': {}, | ||
'export function await() { }': {}, | ||
'export async function foo(x) { await x; }': {}, | ||
"import async from 'foo'": {}, | ||
"import await from 'foo'": {}, | ||
}, | ||
'Invalid Async Generators': { | ||
'async function *foo() {}' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'async function *ft<T>(a: T): void {}' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'class C { async *m() {} }' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'class C { async *mt<T>(a: T): void {} }' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'class C { static async *m(a): void {} }' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'class C { static async *mt<T>(a: T): void {} }' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'var e = async function *() {};' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'var et = async function*<T> (a: T): void {};' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
'var n = new async function*() {};' : { | ||
'errors': { | ||
'0.message': 'A function may not be both async and a generator', | ||
}, | ||
}, | ||
}, | ||
'Async Arrow Functions': { | ||
'var x = async () => await promise;': {}, | ||
'var x = async (a) => await a;': {}, | ||
'var x = async a => await a;': {}, | ||
'var x = async => async + 1;': {}, | ||
'var x = async (a => a + 1);': {}, | ||
'var x = async(x)': {}, | ||
'var x = async (a, b) => await a + b;': { | ||
'body.0.declarations.0.init.body': { | ||
'type': 'BinaryExpression', | ||
}, | ||
}, | ||
'var x = async (a, b, c, d, e, f, g) => await a + await b + c + d + e + f + g;': {}, | ||
'var x = 1 y => y': { | ||
'errors': { | ||
'0.message': 'Unexpected identifier', | ||
}, | ||
}, | ||
'var x = async\ny => y': { | ||
'body.length': 2, | ||
}, | ||
} | ||
}; |
@@ -165,2 +165,3 @@ #!/usr/bin/env node | ||
console.log("%d/%d tests passed", num_successes, num_successes + num_failures); | ||
process.exit(1); | ||
} | ||
@@ -167,0 +168,0 @@ } |
@@ -122,2 +122,3 @@ #!/usr/bin/env node | ||
} | ||
process.exit(1); | ||
} | ||
@@ -124,0 +125,0 @@ } |
@@ -20,3 +20,3 @@ #!/usr/bin/env node | ||
} | ||
console.log(util.inspect(flow.parse(content), {showHidden: false, depth: null})); | ||
console.log(JSON.stringify(flow.parse(content), null, 2)); | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found.
Found 1 instance in 1 package
526377
18
14503
38
80