From d0016fd2f148d85660ab019b6e0f50dc76a530f6 Mon Sep 17 00:00:00 2001 From: Nat Mote Date: Thu, 8 Nov 2018 17:41:48 -0800 Subject: [PATCH] Add the location of function signatures to the AST Summary: This was reconstructed later in `statement.ml`. Now we construct the location in the parser so we don't need to use `Loc.btwn`. Reviewed By: mroch Differential Revision: D12944974 fbshipit-source-id: 03cbd8a935499fe0e7a9c8596dd56bb36be46ee5 --- src/parser/declaration_parser.ml | 54 ++++++------ src/parser/expression_parser.ml | 63 +++++++------- src/parser/flow_ast.ml | 5 ++ src/parser/object_parser.ml | 82 +++++++++++-------- src/parser_utils/ast_builder.ml | 1 + src/parser_utils/flow_ast_differ.ml | 4 +- src/parser_utils/flow_ast_mapper.ml | 4 +- .../flow_polymorphic_ast_mapper.ml | 5 +- .../output/js_layout_generator.ml | 14 ++-- src/parser_utils/scope_builder.ml | 4 +- .../signature_builder_generate.ml | 12 +-- src/typing/statement.ml | 21 ++--- src/typing/typed_ast.ml | 1 + testgen/syntax_base.ml | 3 +- 14 files changed, 149 insertions(+), 124 deletions(-) diff --git a/src/parser/declaration_parser.ml b/src/parser/declaration_parser.ml index 7c95816fee2..12c91c25aab 100644 --- a/src/parser/declaration_parser.ml +++ b/src/parser/declaration_parser.ml @@ -219,33 +219,36 @@ module Declaration let _function = with_loc (fun env -> let async = async env in - Expect.token env T_FUNCTION; - let generator = generator env in - let (tparams, id) = ( - match in_export env, Peek.token env with - | true, T_LPAREN -> (None, None) - | true, T_LESS_THAN -> - let typeParams = Type.type_parameter_declaration env in - let id = if Peek.token env = T_LPAREN then None else Some ( - Parse.identifier ~restricted_error:Error.StrictFunctionName env - ) in - (typeParams, id) - | _ -> - let id = - Parse.identifier ~restricted_error:Error.StrictFunctionName env + let sig_loc, (generator, tparams, id, params, return, predicate) = with_loc (fun env -> + Expect.token env T_FUNCTION; + let generator = generator env in + let (tparams, id) = ( + match in_export env, Peek.token env with + | true, T_LPAREN -> (None, None) + | true, T_LESS_THAN -> + let typeParams = Type.type_parameter_declaration env in + let id = if Peek.token env = T_LPAREN then None else Some ( + Parse.identifier ~restricted_error:Error.StrictFunctionName env + ) in + (typeParams, id) + | _ -> + let id = + Parse.identifier ~restricted_error:Error.StrictFunctionName env + in + (Type.type_parameter_declaration env, Some id) + ) in + let params = + let yield, await = match async, generator with + | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorDeclaration *) + | true, false -> false, allow_await env (* #prod-AsyncFunctionDeclaration *) + | false, true -> true, false (* #prod-GeneratorDeclaration *) + | false, false -> false, false (* #prod-FunctionDeclaration *) in - (Type.type_parameter_declaration env, Some id) - ) in - let params = - let yield, await = match async, generator with - | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorDeclaration *) - | true, false -> false, allow_await env (* #prod-AsyncFunctionDeclaration *) - | false, true -> true, false (* #prod-GeneratorDeclaration *) - | false, false -> false, false (* #prod-FunctionDeclaration *) + function_params ~await ~yield env in - function_params ~await ~yield env - in - let (return, predicate) = Type.annotation_and_predicate_opt env in + let (return, predicate) = Type.annotation_and_predicate_opt env in + (generator, tparams, id, params, return, predicate) + ) env in let _, body, strict = function_body env ~async ~generator in let simple = is_simple_function_params params in strict_post_check env ~strict ~simple id params; @@ -258,6 +261,7 @@ module Declaration predicate; return; tparams; + sig_loc; } ) diff --git a/src/parser/expression_parser.ml b/src/parser/expression_parser.ml index 3ce7e01f075..5de70dca5ea 100644 --- a/src/parser/expression_parser.ml +++ b/src/parser/expression_parser.ml @@ -792,31 +792,34 @@ module Expression and _function env = let start_loc = Peek.loc env in let async = Declaration.async env in - Expect.token env T_FUNCTION; - let generator = Declaration.generator env in - let yield, await = match async, generator with - | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorExpression *) - | true, false -> false, true (* #prod-AsyncFunctionExpression *) - | false, true -> true, false (* #prod-GeneratorExpression *) - | false, false -> false, false (* #prod-FunctionExpression *) - in - let id, tparams = - if Peek.token env = T_LPAREN - then None, None - else begin - let id = match Peek.token env with - | T_LESS_THAN -> None - | _ -> - let env = env |> with_allow_await await |> with_allow_yield yield in - Some (Parse.identifier ~restricted_error:Error.StrictFunctionName env) in - id, Type.type_parameter_declaration env - end in - - (* #sec-function-definitions-static-semantics-early-errors *) - let env = env |> with_allow_super No_super in - - let params = Declaration.function_params ~await ~yield env in - let return, predicate = Type.annotation_and_predicate_opt env in + let sig_loc, (id, params, generator, predicate, return, tparams) = with_loc (fun env -> + Expect.token env T_FUNCTION; + let generator = Declaration.generator env in + let yield, await = match async, generator with + | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorExpression *) + | true, false -> false, true (* #prod-AsyncFunctionExpression *) + | false, true -> true, false (* #prod-GeneratorExpression *) + | false, false -> false, false (* #prod-FunctionExpression *) + in + let id, tparams = + if Peek.token env = T_LPAREN + then None, None + else begin + let id = match Peek.token env with + | T_LESS_THAN -> None + | _ -> + let env = env |> with_allow_await await |> with_allow_yield yield in + Some (Parse.identifier ~restricted_error:Error.StrictFunctionName env) in + id, Type.type_parameter_declaration env + end in + + (* #sec-function-definitions-static-semantics-early-errors *) + let env = env |> with_allow_super No_super in + + let params = Declaration.function_params ~await ~yield env in + let return, predicate = Type.annotation_and_predicate_opt env in + (id, params, generator, predicate, return, tparams) + ) env in let end_loc, body, strict = Declaration.function_body env ~async ~generator in let simple = Declaration.is_simple_function_params params in @@ -830,6 +833,7 @@ module Expression predicate; return; tparams; + sig_loc; })) and number env kind raw = @@ -1077,8 +1081,8 @@ module Expression (* a T_ASYNC could either be a parameter name or it could be indicating * that it's an async function *) let async = Peek.ith_token ~i:1 env <> T_ARROW && Declaration.async env in - let tparams = Type.type_parameter_declaration env in - let params, return, predicate = + let sig_loc, (tparams, params, return, predicate) = with_loc (fun env -> + let tparams = Type.type_parameter_declaration env in (* Disallow all fancy features for identifier => body *) if Peek.is_identifier env && tparams = None then @@ -1089,6 +1093,7 @@ module Expression annot= Ast.Type.Missing (Peek.loc_skip_lookahead env); optional=false; } in + tparams, (loc, { Ast.Function.Params.params = [param]; rest = None }), Ast.Type.Missing Loc.({ loc with start = loc._end }), None @@ -1105,7 +1110,8 @@ module Expression let return, predicate = env |> with_no_anon_function_type true |> Type.annotation_and_predicate_opt in - params, return, predicate in + tparams, params, return, predicate + ) 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 @@ -1142,6 +1148,7 @@ module Expression predicate; return; tparams; + sig_loc; })) and sequence env acc = diff --git a/src/parser/flow_ast.ml b/src/parser/flow_ast.ml index 1d63ef5333f..dc6f9f73a0d 100644 --- a/src/parser/flow_ast.ml +++ b/src/parser/flow_ast.ml @@ -1302,6 +1302,11 @@ and Function : sig predicate: ('M, 'T) Type.Predicate.t option; return: ('M, 'T) Type.annotation_or_hint; tparams: ('M, 'T) Type.ParameterDeclaration.t option; + (* Location of the signature portion of a function, e.g. + * function foo(): void {} + * ^^^^^^^^^^^^^^^^^^^^ + *) + sig_loc: 'M; } and ('M, 'T) body = diff --git a/src/parser/object_parser.ml b/src/parser/object_parser.ml index fee95b7b43f..d2801e79ed2 100644 --- a/src/parser/object_parser.ml +++ b/src/parser/object_parser.ml @@ -87,21 +87,24 @@ module Object (* #sec-function-definitions-static-semantics-early-errors *) let env = env |> with_allow_super Super_prop in - (* It's not clear how type params on getters & setters would make sense - * in Flow's type system. Since this is a Flow syntax extension, we might - * as well disallow it until we need it *) - let tparams = None in - let params = Declaration.function_params ~await:false ~yield:false env in - begin match is_getter, params with - | true, (_, { Ast.Function.Params.params = []; rest = None }) -> () - | false, (_, { Ast.Function.Params.rest = Some _; _ }) -> - (* rest params don't make sense on a setter *) - error_at env (key_loc, Error.SetterArity) - | false, (_, { Ast.Function.Params.params = [_]; _ }) -> () - | true, _ -> error_at env (key_loc, Error.GetterArity) - | false, _ -> error_at env (key_loc, Error.SetterArity) - end; - let return = Type.annotation_opt env in + let sig_loc, (tparams, params, return) = with_loc (fun env -> + (* It's not clear how type params on getters & setters would make sense + * in Flow's type system. Since this is a Flow syntax extension, we might + * as well disallow it until we need it *) + let tparams = None in + let params = Declaration.function_params ~await:false ~yield:false env in + begin match is_getter, params with + | true, (_, { Ast.Function.Params.params = []; rest = None }) -> () + | false, (_, { Ast.Function.Params.rest = Some _; _ }) -> + (* rest params don't make sense on a setter *) + error_at env (key_loc, Error.SetterArity) + | false, (_, { Ast.Function.Params.params = [_]; _ }) -> () + | true, _ -> error_at env (key_loc, Error.GetterArity) + | false, _ -> error_at env (key_loc, Error.SetterArity) + end; + let return = Type.annotation_opt env in + (tparams, params, return) + ) env in let _, body, strict = Declaration.function_body env ~async ~generator in let simple = Declaration.is_simple_function_params params in Declaration.strict_post_check env ~strict ~simple None params; @@ -114,6 +117,7 @@ module Object predicate = None; (* setters/getter are not predicates *) return; tparams; + sig_loc; } ) env in key, value @@ -170,17 +174,20 @@ module Object (* #sec-function-definitions-static-semantics-early-errors *) let env = env |> with_allow_super Super_prop in - let tparams = Type.type_parameter_declaration env in - let params = - let yield, await = match async, generator with - | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorMethod *) - | true, false -> false, allow_await env (* #prod-AsyncMethod *) - | false, true -> true, false (* #prod-GeneratorMethod *) - | false, false -> false, false (* #prod-MethodDefinition *) + let sig_loc, (tparams, params, return) = with_loc (fun env -> + let tparams = Type.type_parameter_declaration env in + let params = + let yield, await = match async, generator with + | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorMethod *) + | true, false -> false, allow_await env (* #prod-AsyncMethod *) + | false, true -> true, false (* #prod-GeneratorMethod *) + | false, false -> false, false (* #prod-MethodDefinition *) + in + Declaration.function_params ~await ~yield env in - Declaration.function_params ~await ~yield env - in - let return = Type.annotation_opt env in + let return = Type.annotation_opt env in + (tparams, params, return) + ) env in let _, body, strict = Declaration.function_body env ~async ~generator in let simple = Declaration.is_simple_function_params params in @@ -195,6 +202,7 @@ module Object predicate = None; return; tparams; + sig_loc; } ) in @@ -532,17 +540,20 @@ module Object env |> with_allow_super Super_prop in let value = with_loc (fun env -> - let tparams = Type.type_parameter_declaration env in - let params = - let yield, await = match async, generator with - | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorMethod *) - | true, false -> false, allow_await env (* #prod-AsyncMethod *) - | false, true -> true, false (* #prod-GeneratorMethod *) - | false, false -> false, false (* #prod-MethodDefinition *) + let sig_loc, (tparams, params, return) = with_loc (fun env -> + let tparams = Type.type_parameter_declaration env in + let params = + let yield, await = match async, generator with + | true, true -> true, true (* proposal-async-iteration/#prod-AsyncGeneratorMethod *) + | true, false -> false, allow_await env (* #prod-AsyncMethod *) + | false, true -> true, false (* #prod-GeneratorMethod *) + | false, false -> false, false (* #prod-MethodDefinition *) + in + Declaration.function_params ~await ~yield env in - Declaration.function_params ~await ~yield env - in - let return = Type.annotation_opt env in + let return = Type.annotation_opt env in + (tparams, params, return) + ) env in let _, body, strict = Declaration.function_body env ~async ~generator in let simple = Declaration.is_simple_function_params params in @@ -557,6 +568,7 @@ module Object predicate = None; return; tparams; + sig_loc; } ) env in Ast.Class.(Body.Method (Loc.btwn start_loc (fst value), { Method. diff --git a/src/parser_utils/ast_builder.ml b/src/parser_utils/ast_builder.ml index 87177a1faff..7b745c867ac 100644 --- a/src/parser_utils/ast_builder.ml +++ b/src/parser_utils/ast_builder.ml @@ -87,6 +87,7 @@ module Functions = struct predicate = None; return = Ast.Type.Missing Loc.none; tparams = None; + sig_loc = Loc.none; } end diff --git a/src/parser_utils/flow_ast_differ.ml b/src/parser_utils/flow_ast_differ.ml index dcec1d126cb..c4ae749b3ab 100644 --- a/src/parser_utils/flow_ast_differ.ml +++ b/src/parser_utils/flow_ast_differ.ml @@ -513,11 +513,11 @@ let program (algo : diff_algorithm) let open Ast.Function in let { id = id1; params = params1; body = body1; async = async1; generator = generator1; - predicate = predicate1; return = return1; tparams = tparams1; + predicate = predicate1; return = return1; tparams = tparams1; sig_loc = _; } = func1 in let { id = id2; params = params2; body = body2; async = async2; generator = generator2; - predicate = predicate2; return = return2; tparams = tparams2; + predicate = predicate2; return = return2; tparams = tparams2; sig_loc = _; } = func2 in if id1 != id2 || (* body handled below *) async1 != async2 diff --git a/src/parser_utils/flow_ast_mapper.ml b/src/parser_utils/flow_ast_mapper.ml index 0db2ba251f8..9272591d905 100644 --- a/src/parser_utils/flow_ast_mapper.ml +++ b/src/parser_utils/flow_ast_mapper.ml @@ -697,7 +697,7 @@ class ['loc] mapper = object(this) let open Flow_ast.Function in let { id = ident; params; body; async; generator; - predicate; return; tparams; + predicate; return; tparams; sig_loc; } = expr in let ident' = map_opt this#function_identifier ident in let params' = this#function_params params in @@ -709,7 +709,7 @@ class ['loc] mapper = object(this) && tparams == tparams' then expr else { id = ident'; params = params'; return = return'; body = body'; - async; generator; predicate; tparams = tparams'; + async; generator; predicate; tparams = tparams'; sig_loc; } method function_params (params: ('loc, 'loc) Flow_ast.Function.Params.t) = diff --git a/src/parser_utils/flow_polymorphic_ast_mapper.ml b/src/parser_utils/flow_polymorphic_ast_mapper.ml index 120ac3de59f..f7d95cd3c4d 100644 --- a/src/parser_utils/flow_polymorphic_ast_mapper.ml +++ b/src/parser_utils/flow_polymorphic_ast_mapper.ml @@ -766,7 +766,7 @@ class virtual ['M, 'T, 'N, 'U] mapper = object(this) let open Ast.Function in let { id = ident; params; body; async; generator; - predicate; return; tparams; + predicate; return; tparams; sig_loc; } = expr in let ident' = Option.map ~f:this#t_function_identifier ident in this#type_parameter_declaration_opt tparams (fun tparams' -> @@ -784,9 +784,10 @@ class virtual ['M, 'T, 'N, 'U] mapper = object(this) BodyExpression (this#expression expr) in let predicate' = Option.map ~f:this#type_predicate predicate in + let sig_loc' = this#on_loc_annot sig_loc in { id = ident'; params = params'; return = return'; body = body'; - async; generator; predicate = predicate'; tparams = tparams'; + async; generator; predicate = predicate'; tparams = tparams'; sig_loc = sig_loc' } ) diff --git a/src/parser_utils/output/js_layout_generator.ml b/src/parser_utils/output/js_layout_generator.ml index bf6ce3bf36d..d43a5dfe25b 100644 --- a/src/parser_utils/output/js_layout_generator.ml +++ b/src/parser_utils/output/js_layout_generator.ml @@ -1211,7 +1211,7 @@ and variable_declarator ~ctxt (loc, { and arrow_function ?(ctxt=normal_context) ~precedence { Ast.Function. params; body; async; predicate; return; tparams; - generator=_; id=_; (* arrows don't have ids and can't be generators *) + generator=_; id=_; (* arrows don't have ids and can't be generators *) sig_loc = _; } = let params_and_stuff = match params, return, predicate, tparams with | (_, { Ast.Function.Params.params = [( @@ -1256,7 +1256,9 @@ and arrow_function ?(ctxt=normal_context) ~precedence { Ast.Function. ] and function_ func = - let { Ast.Function.id; params; body; async; generator; predicate; return; tparams; } = func in + let { + Ast.Function.id; params; body; async; generator; predicate; return; tparams; sig_loc = _; + } = func in let prefix = let s_func = fuse [ Atom "function"; @@ -1350,7 +1352,7 @@ and class_method ( let module M = Ast.Class.Method in let { Ast.Function. params; body; async; generator; predicate; return; tparams; - id = _; (* methods don't use id; see `key` *) + id = _; (* methods don't use id; see `key` *) sig_loc = _; } = func in source_location_with_comments (loc, begin let s_key = object_property_key key in @@ -1583,7 +1585,7 @@ and object_property property = | O.Property (loc, O.Property.Method { key; value = (fn_loc, func) }) -> let s_key = object_property_key key in let { Ast.Function. - id; params; body; async; generator; predicate; return; tparams; + id; params; body; async; generator; predicate; return; tparams; sig_loc = _; } = func in assert (id = None); (* methods don't have ids, see `key` *) let prefix = fuse [ @@ -1599,7 +1601,7 @@ and object_property property = ) | O.Property (loc, O.Property.Get { key; value = (fn_loc, func) }) -> let { Ast.Function. - id; params; body; async; generator; predicate; return; tparams; + id; params; body; async; generator; predicate; return; tparams; sig_loc = _; } = func in assert (id = None); (* getters don't have ids, see `key` *) assert (not async); (* getters can't be async *) @@ -1617,7 +1619,7 @@ and object_property property = ) | O.Property (loc, O.Property.Set { key; value = (fn_loc, func) }) -> let { Ast.Function. - id; params; body; async; generator; predicate; return; tparams; + id; params; body; async; generator; predicate; return; tparams; sig_loc = _; } = func in assert (id = None); (* setters don't have ids, see `key` *) assert (not async); (* setters can't be async *) diff --git a/src/parser_utils/scope_builder.ml b/src/parser_utils/scope_builder.ml index 79f521ef07c..9d0dd65bd24 100644 --- a/src/parser_utils/scope_builder.ml +++ b/src/parser_utils/scope_builder.ml @@ -257,7 +257,7 @@ module Make let open Ast.Function in let { id; params; body; async = _; generator = _; - predicate = _; return = _; tparams = _; + predicate = _; return = _; tparams = _; sig_loc = _; } = expr in run_opt this#function_identifier id; @@ -279,7 +279,7 @@ module Make let open Ast.Function in let { id; params; body; async = _; generator = _; - predicate = _; return = _; tparams = _; + predicate = _; return = _; tparams = _; sig_loc = _; } = expr in let bindings = match id with diff --git a/src/parser_utils/signature_builder_generate.ml b/src/parser_utils/signature_builder_generate.ml index 193e30bd1ec..c0b381f873c 100644 --- a/src/parser_utils/signature_builder_generate.ml +++ b/src/parser_utils/signature_builder_generate.ml @@ -714,7 +714,7 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct let open Ast.Function in let { generator; tparams; params; return; body; - id = _; async = _; predicate = _; + id = _; async = _; predicate = _; sig_loc = _; } = stuff in loc, T.Function (function_ generator tparams params return body) | loc, Object stuff -> @@ -897,7 +897,7 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct let x = object_key key in let loc, { Ast.Function.generator; tparams; params; return; body; - id = _; async = _; predicate = _; + id = _; async = _; predicate = _; sig_loc = _; } = value in (elem_loc, T.CMethod (x, kind, static, (loc, function_ generator tparams params return body))) :: acc @@ -957,7 +957,7 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct let open Ast.Function in let { generator; tparams; params; return; body; - id = _; async = _; predicate = _; + id = _; async = _; predicate = _; sig_loc = _; } = fn in loc, T.OMethod (x, (fn_loc, function_ generator tparams params return body)) | loc, Get { key; value = (fn_loc, fn) } -> @@ -965,7 +965,7 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct let open Ast.Function in let { generator; tparams; params; return; body; - id = _; async = _; predicate = _; + id = _; async = _; predicate = _; sig_loc = _; } = fn in loc, T.OGet (x, (fn_loc, function_ generator tparams params return body)) | loc, Set { key; value = (fn_loc, fn) } -> @@ -973,7 +973,7 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct let open Ast.Function in let { generator; tparams; params; return; body; - id = _; async = _; predicate = _; + id = _; async = _; predicate = _; sig_loc = _; } = fn in loc, T.OSet (x, (fn_loc, function_ generator tparams params return body)) in @@ -1135,7 +1135,7 @@ module Generator(Env: Signature_builder_verify.EvalEnv) = struct | Declaration (loc, Ast.Statement.FunctionDeclaration ({ Ast.Function.id = None; generator; tparams; params; return; body; - async = _; predicate = _; + async = _; predicate = _; sig_loc = _; })) -> `Expr (loc, T.Function (Eval.function_ generator tparams params return body)) | Declaration (loc, Ast.Statement.ClassDeclaration ({ Ast.Class.id = Some _; _ } as class_)) -> diff --git a/src/typing/statement.ml b/src/typing/statement.ml index 76babf06fc0..5f672b17c2c 100644 --- a/src/typing/statement.ml +++ b/src/typing/statement.ml @@ -272,7 +272,7 @@ and statement_decl cx = Ast.Statement.( | (loc, DeclareFunction ({ DeclareFunction. id = (id_loc, name); _; } as declare_function)) -> - (match declare_function_to_function_declaration cx declare_function with + (match declare_function_to_function_declaration cx loc declare_function with | None -> let r = mk_reason (RCustom (spf "declare %s" name)) loc in let t = Tvar.mk cx r in @@ -1657,12 +1657,7 @@ and statement cx : 'a -> (ALoc.t, ALoc.t * Type.t) Ast.Statement.t = Ast.Stateme | (_, Debugger) as stmt -> stmt | (loc, FunctionDeclaration func) -> - let {Ast.Function.id; params; return; _} = func in - let sig_loc = match params, return with - | _, Ast.Type.Available (end_loc, _) - | (end_loc, _), Ast.Type.Missing _ - -> Loc.btwn (ALoc.to_loc loc) (ALoc.to_loc end_loc) |> ALoc.of_loc - in + let {Ast.Function.id; sig_loc; _} = func in let fn_type, func_ast = mk_function None cx sig_loc func in let type_table_loc = Type_table.function_decl_loc id loc in Type_table.set (Context.type_table cx) type_table_loc fn_type; @@ -1693,7 +1688,7 @@ and statement cx : 'a -> (ALoc.t, ALoc.t * Type.t) Ast.Statement.t = Ast.Stateme } | (loc, DeclareFunction declare_function) -> - (match declare_function_to_function_declaration cx declare_function with + (match declare_function_to_function_declaration cx loc declare_function with | Some (func_decl, reconstruct_ast) -> loc, DeclareFunction (reconstruct_ast (statement cx (loc, func_decl))) | None -> @@ -3111,12 +3106,7 @@ and expression_ ~is_cond cx loc e : (ALoc.t, ALoc.t * Type.t) Ast.Expression.t = (loc, t), Sequence { Sequence.expressions } | Function func -> - let {Ast.Function.id; params; return; predicate; _} = func in - let sig_loc = match params, return with - | _, Ast.Type.Available (end_loc, _) - | (end_loc, _), Ast.Type.Missing _ - -> Loc.btwn (ALoc.to_loc loc) (ALoc.to_loc end_loc) |> ALoc.of_loc - in + let {Ast.Function.id; predicate; sig_loc; _} = func in (match predicate with | Some (_, Ast.Type.Predicate.Inferred) -> @@ -6582,7 +6572,7 @@ and mk_arrow cx loc func = predicate declared for the funcion *) (* Also returns a function for reversing this process, for the sake of typed AST construction. *) -and declare_function_to_function_declaration cx +and declare_function_to_function_declaration cx declare_loc { Ast.Statement.DeclareFunction.id; annot; predicate; } = match predicate with | Some (loc, Ast.Type.Predicate.Inferred) -> @@ -6638,6 +6628,7 @@ and declare_function_to_function_declaration cx predicate = Some (loc, Ast.Type.Predicate.Inferred); return; tparams; + sig_loc = declare_loc; }, function | _, Ast.Statement.FunctionDeclaration { Ast.Function. id = Some ((id_loc, fun_type), id_name); diff --git a/src/typing/typed_ast.ml b/src/typing/typed_ast.ml index 5db906b4d12..43fbca67e21 100644 --- a/src/typing/typed_ast.ml +++ b/src/typing/typed_ast.ml @@ -188,6 +188,7 @@ module Function = struct predicate = None; return = Ast.Type.Missing error_annot; tparams = None; + sig_loc = ALoc.none; } end diff --git a/testgen/syntax_base.ml b/testgen/syntax_base.ml index 0ede93fa72c..1074204cc1b 100644 --- a/testgen/syntax_base.ml +++ b/testgen/syntax_base.ml @@ -168,7 +168,8 @@ let mk_func_def generator = false; predicate = None; return = T.Available (Loc.none, (Loc.none, rtype)); - tparams = None} in + tparams = None; + sig_loc = Loc.none} in Stmt (S.FunctionDeclaration func) let mk_func_call (fid : (Loc.t, Loc.t) E.t') (param : (Loc.t, Loc.t) E.t') : t =