Skip to content

Commit

Permalink
Allow declaration files to declare generator functions
Browse files Browse the repository at this point in the history
  • Loading branch information
samwgoldman committed Jun 17, 2015
1 parent f551050 commit cce04ec
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/parser/parser_flow.ml
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,12 @@ end = struct
match param_list_or_type env with
| ParamList (rest, params) ->
Expect.token env T_ARROW;
let generator = false in
let returnType = _type env in
let end_loc = fst returnType in
Loc.btwn start_loc end_loc, Type.(Function Function.({
params;
generator;
returnType;
rest;
typeParameters = None;
Expand All @@ -496,10 +498,12 @@ end = struct
let typeParameters = type_parameter_declaration env in
let rest, params = function_param_list env in
Expect.token env T_ARROW;
let generator = false in
let returnType = _type env in
let end_loc = fst returnType in
Loc.btwn start_loc end_loc, Type.(Function Function.({
params;
generator;
returnType;
rest;
typeParameters;
Expand All @@ -510,10 +514,12 @@ end = struct
let typeParameters = type_parameter_declaration env in
let rest, params = function_param_list env in
Expect.token env T_COLON;
let generator = false in
let returnType = _type env in
let loc = Loc.btwn start_loc (fst returnType) in
loc, Type.Function.({
params;
generator;
returnType;
rest;
typeParameters;
Expand Down Expand Up @@ -2853,7 +2859,9 @@ end = struct
})) in

let declare_function env start_loc =
let async = Declaration.async env in
Expect.token env T_FUNCTION;
let generator = Declaration.generator env async in
let id = Parse.identifier env in
let start_sig_loc = Peek.loc env in
let typeParameters = Type.type_parameter_declaration env in
Expand All @@ -2864,6 +2872,7 @@ end = struct
let loc = Loc.btwn start_sig_loc end_loc in
let value = loc, Ast.Type.(Function {Function.
params;
generator;
returnType;
rest;
typeParameters;
Expand Down
1 change: 1 addition & 0 deletions src/parser/spider_monkey_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ and Type : sig

type t = {
params: Param.t list;
generator: bool;
returnType: Type.t;
rest: Param.t option;
typeParameters: Type.ParameterDeclaration.t option;
Expand Down
20 changes: 17 additions & 3 deletions src/typing/type_inference_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,7 @@ let rec convert cx map = Ast.Type.(function
mk_nominal_type_ cx reason map (c, params)
)

(* TODO: unsupported generators *)
| loc, Function { Function.params; returnType; rest; typeParameters } ->
| loc, Function { Function.params; generator; returnType; rest; typeParameters } ->
let typeparams, map_ = mk_type_param_declarations cx ~map typeParameters in
let map = SMap.fold SMap.add map_ map in

Expand All @@ -797,6 +796,21 @@ let rec convert cx map = Ast.Type.(function
((snd name).Ast.Identifier.name) :: rev_pnames
| None -> rev_tlist, rev_pnames
) in
let ret = convert cx map returnType in
let ret =
if generator then
let reason = mk_reason "generator type" loc in
let yield = Flow_js.mk_tvar cx (prefix_reason "yield of " reason) in
let return = Flow_js.mk_tvar cx (prefix_reason "return of " reason) in
let next = Flow_js.mk_tvar cx (prefix_reason "next of " reason) in
let gt = Flow_js.get_builtin_typeapp
cx
reason
"Generator"
[yield; return; next] in
Flow_js.flow cx (ret, gt);
gt
else ret in
let ft =
FunT (
mk_reason "function type" loc,
Expand All @@ -806,7 +820,7 @@ let rec convert cx map = Ast.Type.(function
this_t = Flow_js.mk_tvar cx (mk_reason "this" loc);
params_tlist = (List.rev rev_params_tlist);
params_names = Some (List.rev rev_params_names);
return_t = convert cx map returnType;
return_t = ret;
closure_t = 0
})
in
Expand Down
14 changes: 13 additions & 1 deletion tests/generators/generators.exp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,16 @@ generators.js:21:10,11: string
This type is incompatible with
generators.js:28:22,28: boolean

Found 6 errors
generators.js:31:37,42: number
This type is incompatible with
generators.js:23:13,18: string

generators.js:31:45,50: string
This type is incompatible with
[LIB] core.js:306:37,39: union type

generators.js:33:29,29: number
This type is incompatible with
generators.js:31:53,59: boolean

Found 9 errors
9 changes: 9 additions & 0 deletions tests/generators/generators.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,12 @@ if (typeof infer_stmt_next === "undefined") {
} else {
(infer_stmt_next : boolean) // error: string ~> boolean
}

declare function *decl(): Generator<number, string, boolean>;
for (var x: string of decl()) {} // error: number ~> string
var decl_next = decl().next(0).value; // error: number ~> boolean
if (typeof decl_next === "undefined") {
} else if (typeof decl_next === "number") {
} else {
(decl_next : boolean) // error: string ~> boolean
}

0 comments on commit cce04ec

Please sign in to comment.