Skip to content

Commit

Permalink
[Parser] Update ast-types and fix up parser
Browse files Browse the repository at this point in the history
Summary: There were a few changes made to ast-types and the parser was no
longer passing the tests. This diff fixes those various issues. The main issues
were:

1. Parser support for class property initializers. Flow still doesn't have proper support for them, but they should at least parse.
2. Class method kinds are now `"constructor", "method", "get" and "set"` instead of `"", "init", "get", "set"`. This matches what babel and esprima are doing, though esprima-fb is still stuck with the old kinds.

Reviewed By: @avikchaudhuri

Differential Revision: D2252999
  • Loading branch information
gabelevi authored and facebook-github-bot-6 committed Jul 17, 2015
1 parent e4a620d commit 7e5b2a9
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 47 deletions.
29 changes: 14 additions & 15 deletions src/parser/estree_translator.ml
Expand Up @@ -613,24 +613,22 @@ end with type t = Impl.t) = struct

and class_method (loc, method_) =
let { Class.Method.key; value; kind; static; } = method_ in
Expression.Object.Property.(
let key, computed = (match key with
let key, computed = Expression.Object.Property.(match key with
| Literal lit -> literal lit, false
| Identifier id -> identifier id, false
| Computed expr -> expression expr, true) in
let kind = match kind with
| Init -> "init"
let kind = Class.Method.(match kind with
| Constructor -> "constructor"
| Method -> "method"
| Get -> "get"
| Set -> "set"
in
node "MethodDefinition" loc [|
"key", key;
"value", function_expression value;
"kind", string kind;
"static", bool static;
"computed", bool computed;
|]
)
| Set -> "set") in
node "MethodDefinition" loc [|
"key", key;
"value", function_expression value;
"kind", string kind;
"static", bool static;
"computed", bool computed;
|]

and class_property (loc, prop) = Class.Property.(
let key, computed = (match prop.key with
Expand All @@ -639,7 +637,8 @@ end with type t = Impl.t) = struct
| Expression.Object.Property.Computed expr -> expression expr, true) in
node "ClassProperty" loc [|
"key", key;
"typeAnnotation", type_annotation prop.typeAnnotation;
"value", option expression prop.value;
"typeAnnotation", option type_annotation prop.typeAnnotation;
"computed", bool computed;
"static", bool prop.static;
|]
Expand Down
2 changes: 1 addition & 1 deletion src/parser/package.json
Expand Up @@ -18,7 +18,7 @@
"esprima-fb": "15001.1.0-dev-harmony-fb"
},
"dependencies": {
"ast-types": "0.7.8",
"ast-types": "0.8.4",
"colors": ">=0.6.2",
"minimist": ">=0.2.0"
},
Expand Down
52 changes: 35 additions & 17 deletions src/parser/parser_flow.ml
Expand Up @@ -214,10 +214,10 @@ end = struct
val type_parameter_declaration : env -> Ast.Type.ParameterDeclaration.t option
val type_parameter_instantiation : env -> Ast.Type.ParameterInstantiation.t option
val generic : env -> Loc.t * Ast.Type.Generic.t
val return_type : env -> Ast.Type.annotation option
val _object : ?allow_static:bool -> env -> Loc.t * Type.Object.t
val function_param_list : env -> Type.Function.Param.t option * Type.Function.Param.t list
val annotation : env -> Ast.Type.annotation
val annotation_opt : env -> Ast.Type.annotation option
end = struct
type param_list_or_type =
| ParamList of (Type.Function.Param.t option * Type.Function.Param.t list)
Expand Down Expand Up @@ -723,7 +723,7 @@ end = struct
let loc, generic = raw_generic_with_identifier env id in
loc, Type.Generic generic

and return_type env =
and annotation_opt env =
match Peek.token env with
| T_COLON -> Some (annotation env)
| _ -> None
Expand All @@ -738,10 +738,10 @@ end = struct
let _type = wrap _type
let type_parameter_declaration = wrap type_parameter_declaration
let type_parameter_instantiation = wrap type_parameter_instantiation
let return_type = wrap return_type
let _object ?(allow_static=false) env = wrap (_object ~allow_static) env
let function_param_list = wrap function_param_list
let annotation = wrap annotation
let annotation_opt = wrap annotation_opt
let generic = wrap generic
end

Expand Down Expand Up @@ -920,7 +920,7 @@ end = struct
) in
let typeParameters = Type.type_parameter_declaration env in
let params, defaults, rest = function_params env in
let returnType = Type.return_type env in
let returnType = Type.annotation_opt env in
let _, body, strict = function_body env ~async ~generator in
let simple = is_simple_function_params params defaults rest in
strict_post_check env ~strict ~simple id params;
Expand Down Expand Up @@ -1530,7 +1530,7 @@ end = struct
id, Type.type_parameter_declaration env
end in
let params, defaults, rest = Declaration.function_params env in
let returnType = Type.return_type env in
let returnType = Type.annotation_opt env in
let end_loc, body, strict =
Declaration.function_body env ~async ~generator in
let simple = Declaration.is_simple_function_params params defaults rest in
Expand Down Expand Up @@ -1774,7 +1774,7 @@ end = struct
[param], [], None, None
else
let params, defaults, rest = Declaration.function_params env in
params, defaults, rest, Type.return_type env in
params, defaults, rest, Type.annotation_opt env in

(* It's hard to tell if an invalid expression was intended to be an
* arrow function before we see the =>. If there are no params, that
Expand Down Expand Up @@ -1957,7 +1957,7 @@ end = struct
[ (fst param, Pattern.Identifier param) ]
| Init -> assert false) in
Expect.token env T_RPAREN;
let returnType = Type.return_type env in
let returnType = Type.annotation_opt env in
let _, body, strict = Declaration.function_body env ~async ~generator in
let defaults = [] in
let rest = None in
Expand Down Expand Up @@ -2053,7 +2053,7 @@ end = struct
| T_LPAREN ->
let typeParameters = Type.type_parameter_declaration env in
let params, defaults, rest = Declaration.function_params env in
let returnType = Type.return_type env in
let returnType = Type.annotation_opt env in
let _, body, strict =
Declaration.function_body env ~async ~generator in
let simple = Declaration.is_simple_function_params params defaults rest in
Expand Down Expand Up @@ -2209,7 +2209,7 @@ end = struct
Ast.Class.(Body.Method (Loc.btwn start_loc end_loc, Method.({
key;
value;
kind = Ast.Expression.Object.Property.Get;
kind = Get;
static;
})))

Expand All @@ -2219,27 +2219,34 @@ end = struct
Ast.Class.(Body.Method (Loc.btwn start_loc end_loc, Method.({
key;
value;
kind = Ast.Expression.Object.Property.Set;
kind = Set;
static;
})))

in let init env start_loc key async generator static =
if not async && not generator && Peek.token env = T_COLON
then begin
match Peek.token env with
| T_COLON
| T_ASSIGN
| T_SEMICOLON when not async && not generator ->
(* Class property with annotation *)
let typeAnnotation = Type.annotation env in
let typeAnnotation = Type.annotation_opt env in
let value =
if Expect.maybe env T_ASSIGN
then Some (Parse.expression env)
else None in
let end_loc = Peek.loc env in
Expect.token env T_SEMICOLON;
let loc = Loc.btwn start_loc end_loc in
Ast.Class.(Body.Property (loc, Property.({
key;
value;
typeAnnotation;
static;
})))
end else begin
| _ ->
let typeParameters = Type.type_parameter_declaration env in
let params, defaults, rest = Declaration.function_params env in
let returnType = Type.return_type env in
let returnType = Type.annotation_opt env in
let _, body, strict =
Declaration.function_body env ~async ~generator in
let simple =
Expand All @@ -2261,13 +2268,24 @@ end = struct
returnType;
typeParameters;
}) in
let kind = Ast.(match key with
| Expression.Object.Property.Identifier (_, {
Identifier.name = "constructor";
_;
})
| Expression.Object.Property.Literal (_, {
Literal.value = Literal.String "constructor";
_;
}) ->
Class.Method.Constructor
| _ ->
Class.Method.Method) in
Ast.Class.(Body.Method (Loc.btwn start_loc end_loc, Method.({
key;
value;
kind = Ast.Expression.Object.Property.Init;
kind;
static;
})))
end

in fun env -> Ast.Expression.Object.Property.(
let start_loc = Peek.loc env in
Expand Down
10 changes: 8 additions & 2 deletions src/parser/spider_monkey_ast.ml
Expand Up @@ -906,8 +906,13 @@ end = Comment
and Class : sig
module Method : sig
type t = Loc.t * t'
and kind =
| Constructor
| Method
| Get
| Set
and t' = {
kind: Expression.Object.Property.kind;
kind: kind;
key: Expression.Object.Property.key;
value: Loc.t * Expression.Function.t;
static: bool;
Expand All @@ -917,7 +922,8 @@ and Class : sig
type t = Loc.t * t'
and t' = {
key: Expression.Object.Property.key;
typeAnnotation: Type.annotation;
value: Expression.t option;
typeAnnotation: Type.annotation option;
static: bool;
}
end
Expand Down
20 changes: 20 additions & 0 deletions src/parser/test/esprima_ast_types.js
@@ -0,0 +1,20 @@
/* This is basically the ast-types main.js, except without the conflicting
* babel definitions */
var types = require("ast-types/lib/types");

// This core module of AST types captures ES5 as it is parsed today by
// git://github.com/ariya/esprima.git#master.
require("ast-types/def/core");

// Feel free to add to or remove from this list of extension modules to
// configure the precise type hierarchy that you need.
require("ast-types/def/es6");
require("ast-types/def/es7");
require("ast-types/def/mozilla");
require("ast-types/def/e4x");
require("ast-types/def/fb-harmony");
require("ast-types/def/esprima");

types.finalize();

exports.namedTypes = types.namedTypes;
19 changes: 18 additions & 1 deletion src/parser/test/esprima_test_runner.js
Expand Up @@ -5,7 +5,7 @@
var esprima = require("esprima-fb");
var flow = require("../flow_parser.js");
var util = require("util");
var ast_types = require("ast-types");
var ast_types = require("./esprima_ast_types.js");

function new_env() {
var diffs = {};
Expand Down Expand Up @@ -183,6 +183,20 @@ function handleSpecialObjectCompare(esprima, flow, env) {
esprima.implements = [];
}
break;
case "ClassBody":
// esprima-fb is pretty out of date here. The 4 kinds should be
// "constructor", "method", "get" and "set"
for (var i = 0; i < esprima.body.length; i++) {
var body = esprima.body[i];
if (body && body.type == "MethodDefinition") {
if (body.key.name === "constructor") {
body.kind = "constructor";
} else if (body.kind === "init" || body.kind === "") {
body.kind = "method";
}
}
}
break;
case 'ArrayPattern':
// Esprima has the wrong node type for spread elements in an array pattern
for (var i = 0; i < esprima.elements.length; i++) {
Expand All @@ -197,8 +211,11 @@ function handleSpecialObjectCompare(esprima, flow, env) {
case 'ObjectTypeProperty':
case 'ObjectTypeIndexer':
case 'ObjectTypeCallProperty':
esprima.static = esprima.static || false;
break;
case 'ClassProperty':
esprima.static = esprima.static || false;
esprima.value = null;
break;
case 'ArrowFunctionExpression':
esprima.returnType = null;
Expand Down
2 changes: 1 addition & 1 deletion src/parser/test/hardcoded_test_runner.js
@@ -1,6 +1,6 @@
var flow = require("./../flow_parser.js");
var util = require("util");
var ast_types = require("ast-types");
var ast_types = require("./esprima_ast_types.js");

function new_env() {
var diffs = {};
Expand Down

0 comments on commit 7e5b2a9

Please sign in to comment.