Skip to content

Commit

Permalink
[flow] add a new IndexContext case to Type.enclosing_context
Browse files Browse the repository at this point in the history
Summary:
* Makes the context of `x` in `o[x]` a special kind of context (`IndexContext`). This flag is now passed alongside the existing conditional context(`cond` parameter), so that it can be used under natural inference to infer more precise types for primitive literals.
* Propagates `cond` flag to a few more expressions in statement.ml (e.g. pattern match cases)

Changelog: [internal]

Reviewed By: SamChou19815

Differential Revision: D70676102

fbshipit-source-id: e29765b12473dbdbf7e33d5fb3f3d245b7787312
  • Loading branch information
panagosg7 authored and facebook-github-bot committed Mar 8, 2025
1 parent 501116a commit 09974ff
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/services/autocomplete/autocomplete_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ module Inference = struct
let type_of_match_member_pattern cx loc mem =
Match_pattern.type_of_member_pattern
cx
~on_identifier:(Statement.identifier ~encl_ctx:Type.NoContext)
~on_identifier:Statement.identifier
~on_expression:Statement.expression
(loc, mem)
end
Expand Down
4 changes: 2 additions & 2 deletions src/typing/match_pattern.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ let rec member cx ~on_identifier ~on_expression mem =
match base with
| BaseIdentifier (loc, id) ->
let exp = (loc, Ast.Expression.Identifier (loc, id)) in
(exp, BaseIdentifier ((loc, on_identifier cx id loc), id))
(exp, BaseIdentifier ((loc, on_identifier ~encl_ctx:Type.OtherTest cx id loc), id))
| BaseMember mem ->
let (exp, mem) = member cx ~on_identifier ~on_expression mem in
(exp, BaseMember mem)
Expand Down Expand Up @@ -179,7 +179,7 @@ let rec pattern_ cx ~on_identifier ~on_expression ~on_binding ~in_or_pattern acc
in
AsPattern { AsPattern.pattern = p; target; comments }
| IdentifierPattern (loc, x) ->
let t = on_identifier cx x loc in
let t = on_identifier ~encl_ctx:Type.OtherTest cx x loc in
IdentifierPattern ((loc, t), x)
| BindingPattern x -> BindingPattern (binding_pattern cx ~on_binding ~in_or_pattern ~loc acc x)
| WildcardPattern x -> WildcardPattern x
Expand Down
6 changes: 4 additions & 2 deletions src/typing/match_pattern.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module Ast = Flow_ast

val pattern :
Context.t ->
on_identifier:(Context.t -> ALoc.t Ast.Identifier.t' -> ALoc.t -> Type.t) ->
on_identifier:
(encl_ctx:Type.enclosing_context -> Context.t -> ALoc.t Ast.Identifier.t' -> ALoc.t -> Type.t) ->
on_expression:
(Context.t -> (ALoc.t, ALoc.t) Ast.Expression.t -> (ALoc.t, ALoc.t * Type.t) Ast.Expression.t) ->
on_binding:
Expand All @@ -20,7 +21,8 @@ val pattern :

val type_of_member_pattern :
Context.t ->
on_identifier:(Context.t -> ALoc.t Ast.Identifier.t' -> ALoc.t -> Type.t) ->
on_identifier:
(encl_ctx:Type.enclosing_context -> Context.t -> ALoc.t Ast.Identifier.t' -> ALoc.t -> Type.t) ->
on_expression:
(Context.t -> (ALoc.t, ALoc.t) Ast.Expression.t -> (ALoc.t, ALoc.t * Type.t) Ast.Expression.t) ->
(ALoc.t, ALoc.t) Ast.MatchPattern.MemberPattern.t ->
Expand Down
30 changes: 19 additions & 11 deletions src/typing/statement.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,8 @@ module Make
Flow_ast.Expression.Identifier (Flow_ast_utils.match_root_ident case_loc)
)
pattern
~on_identifier:(fun cx -> identifier cx empty_syntactic_flags)
~on_identifier:(fun ~encl_ctx cx ->
identifier cx { empty_syntactic_flags with Primitive_literal.encl_ctx })
~on_expression:expression
~on_binding:(fun ~use_op ~name_loc ~kind name t ->
init_var kind cx ~use_op t name_loc;
Expand Down Expand Up @@ -2493,7 +2494,7 @@ module Make
shorthand;
}
) ->
let (((_, kt), _) as k') = expression cx k in
let (((_, kt), _) as k') = expression cx ~encl_ctx:IndexContext k in
let (((_, vt), _) as v') = expression cx ~as_const v in
let computed = mk_computed k kt vt in
( ObjectExpressionAcc.add_computed cx computed acc,
Expand All @@ -2516,7 +2517,7 @@ module Make
value = (fn_loc, fn);
}
) ->
let (((_, kt), _) as k') = expression cx k in
let (((_, kt), _) as k') = expression cx ~encl_ctx:IndexContext k in
let ((_, vt), v') = expression cx (fn_loc, Ast.Expression.Function fn) in
let fn =
match v' with
Expand Down Expand Up @@ -2946,7 +2947,8 @@ module Make
cx
(case_loc, Identifier (Flow_ast_utils.match_root_ident case_loc))
pattern
~on_identifier:(fun cx -> identifier cx empty_syntactic_flags)
~on_identifier:(fun ~encl_ctx cx ->
identifier cx { empty_syntactic_flags with Primitive_literal.encl_ctx })
~on_expression:expression
~on_binding:(fun ~use_op ~name_loc ~kind name t ->
init_var kind cx ~use_op t name_loc;
Expand Down Expand Up @@ -4539,7 +4541,7 @@ module Make
)
in
let eval_index () =
let (((_, tind), _) as index) = expression cx index in
let (((_, tind), _) as index) = expression ~encl_ctx:IndexContext cx index in
(tind, index)
in
let conf =
Expand Down Expand Up @@ -4836,7 +4838,7 @@ module Make
)
in
let eval_args_and_expr () =
let (((_, elem_t), _) as expr) = expression cx expr in
let (((_, elem_t), _) as expr) = expression ~encl_ctx:IndexContext cx expr in
let (argts, arguments_ast) = arg_list cx arguments in
((argts, elem_t), (arguments_ast, expr))
in
Expand Down Expand Up @@ -4973,7 +4975,8 @@ module Make
| SwitchTest _
| OtherTest ->
BoolModuleT.at loc
| NoContext ->
| NoContext
| IndexContext ->
let reason = mk_reason (RUnaryOperator ("not", desc_of_t arg)) loc in
Operators.unary_not cx reason arg
in
Expand Down Expand Up @@ -5074,7 +5077,9 @@ module Make
and visit_eq_test cx ~encl_ctx loc left right =
let check ~encl_ctx = expression cx ~encl_ctx in
match encl_ctx with
| NoContext -> check ~encl_ctx:NoContext
| NoContext
| IndexContext ->
check ~encl_ctx
| SwitchTest _
| OtherTest ->
let reconstruct_ast = check ~encl_ctx:OtherTest in
Expand Down Expand Up @@ -5142,7 +5147,9 @@ module Make
let (((_, t2), _) as right) = reconstruct_ast right in
begin
match encl_ctx with
| NoContext -> ()
| NoContext
| IndexContext ->
()
| SwitchTest _
| OtherTest ->
matching_prop_check cx left right;
Expand Down Expand Up @@ -5452,7 +5459,7 @@ module Make
let reason = mk_reason (RPropertyAssignment None) lhs_loc in
let lhs_reason = mk_expression_reason _object in
let (o, _object) = typecheck_object _object in
let (((_, i), _) as index) = expression cx index in
let (((_, i), _) as index) = expression ~encl_ctx:IndexContext cx index in
let use_op = make_op ~lhs:reason ~prop:(mk_reason (desc_of_reason lhs_prop_reason) iloc) in
let upper = maybe_chain lhs_reason (SetElemT (use_op, reason, i, mode, t, None)) in
Flow.flow cx (o, upper);
Expand Down Expand Up @@ -6471,7 +6478,8 @@ module Make
| SwitchTest _
| OtherTest ->
OptTestPropT (use_op, reason, id, mk_named_prop ~reason:prop_reason prop_name, hint)
| NoContext ->
| NoContext
| IndexContext ->
OptGetPropT
{
use_op;
Expand Down
2 changes: 2 additions & 0 deletions src/typing/type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,8 @@ module rec TypeTerm : sig
}
(* `if(C){}`, `while(C){}`, `C?e1:e2`, `invariant(C)`, ... *)
| OtherTest
(* `o[C]`, `o[C]=e`, `{[C]:e}`, `o[C]()` *)
| IndexContext

(* Bindings created from destructuring annotations should themselves act like
* annotations. That is, `var {p}: {p: string}; p = 0` should be an error,
Expand Down
2 changes: 2 additions & 0 deletions src/typing/type_operation_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ module Operators = struct
explanation = None;
}
| NoContext
| IndexContext
| OtherTest ->
let reasons = FlowError.ordered_reasons (reason_of_t l, reason_of_t r) in
Error_message.EComparison reasons)
Expand All @@ -282,6 +283,7 @@ module Operators = struct
match encl_ctx with
| SwitchTest _ -> Some (Lazy.force comparison_error)
| NoContext
| IndexContext
| OtherTest ->
None
end
Expand Down

0 comments on commit 09974ff

Please sign in to comment.