Skip to content

Commit

Permalink
[flow] Separately handle string/any typed computed property vs other …
Browse files Browse the repository at this point in the history
…invalid computed properties

Summary:
In this diff, we will detect the kinds of computed property types by inlining the check of `WriteComputedObjPropCheckT`. We do not need another concretization pass, since we are already given the concretized keys here.

For string and any typed keys, we will continue to go through the `ObjectExpressionAcc.ComputedProp.NonLiteralKey` variant, which is unsound, but will be fixed later. For number and other kinds of keys, we will error, and as a result, we can safely ignore them.

Changelog: [internal]

Reviewed By: panagosg7

Differential Revision: D66968683

fbshipit-source-id: 1ee1befcd52d88244061efe6ba533c7dbde8391a
  • Loading branch information
SamChou19815 authored and facebook-github-bot committed Dec 10, 2024
1 parent eda5ce1 commit facff9a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 30 deletions.
29 changes: 14 additions & 15 deletions src/typing/flow_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5247,20 +5247,19 @@ struct
| (AnyT (_, src), WriteComputedObjPropCheckT { reason; value_t; _ }) ->
let src = any_mod_src_keep_placeholder Untyped src in
rec_flow_t cx trace ~use_op:unknown_use (value_t, AnyT.why src reason)
| (DefT (_, StrT _), WriteComputedObjPropCheckT { err_on_str_key; _ }) ->
Base.Option.iter err_on_str_key ~f:(fun (use_op, reason_obj) ->
add_output
cx
(Error_message.EPropNotFound
{
prop_name = None;
reason_prop = TypeUtil.reason_of_t l;
reason_obj;
use_op;
suggestion = None;
}
)
)
| (DefT (_, StrT _), WriteComputedObjPropCheckT { err_on_str_key = (use_op, reason_obj); _ })
->
add_output
cx
(Error_message.EPropNotFound
{
prop_name = None;
reason_prop = TypeUtil.reason_of_t l;
reason_obj;
use_op;
suggestion = None;
}
)
| (DefT (reason, NumT lit), WriteComputedObjPropCheckT { reason_key; _ }) ->
let kind = Flow_intermediate_error_types.InvalidObjKey.kind_of_num_lit lit in
add_output cx (Error_message.EObjectComputedPropertyAssign (reason, reason_key, kind))
Expand Down Expand Up @@ -7295,7 +7294,7 @@ struct
reason = TypeUtil.reason_of_t elem_t;
reason_key = None;
value_t = tin;
err_on_str_key = Some (use_op, reason_obj);
err_on_str_key = (use_op, reason_obj);
}
))

Expand Down
28 changes: 21 additions & 7 deletions src/typing/statement.ml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ module Make
name: Reason.name;
prop: Type.property;
}
| IgnoredInvalidNonLiteralKey
| NonLiteralKey of {
key: Type.t;
value: Type.t;
Expand Down Expand Up @@ -122,6 +123,7 @@ module Make
let add_computed cx computed acc =
match computed with
| ComputedProp.Named { name; prop } -> add_prop (NameUtils.Map.add name prop) acc
| ComputedProp.IgnoredInvalidNonLiteralKey -> acc
| ComputedProp.NonLiteralKey { key = _; value = _; reason_obj } ->
(* No properties are added in this case. *)
add_spread (Obj_type.mk ~obj_kind:Exact cx reason_obj) acc
Expand Down Expand Up @@ -2262,13 +2264,25 @@ module Make
and create_computed_prop cx key_loc keys ~reason ~reason_key ~reason_obj ~as_const ~frozen value =
let single_key key =
match Flow_js_utils.propref_for_elem_t key with
| Computed elem_t ->
let check =
WriteComputedObjPropCheckT
{ reason; reason_key = Some reason_key; value_t = value; err_on_str_key = None }
in
Flow.flow cx (elem_t, check);
ObjectExpressionAcc.ComputedProp.NonLiteralKey { key; value; reason_obj }
| Computed key ->
(match key with
| DefT (_, StrT _)
| AnyT _ ->
ObjectExpressionAcc.ComputedProp.NonLiteralKey { key; value; reason_obj }
| DefT (reason_key, NumT lit) ->
let kind = Flow_intermediate_error_types.InvalidObjKey.kind_of_num_lit lit in
Flow_js_utils.add_output
cx
(Error_message.EObjectComputedPropertyAssign (reason, Some reason_key, kind));
ObjectExpressionAcc.ComputedProp.IgnoredInvalidNonLiteralKey
| _ ->
let reason = reason_of_t key in
Flow_js_utils.add_output
cx
(Error_message.EObjectComputedPropertyAssign
(reason, Some reason_key, Flow_intermediate_error_types.InvalidObjKey.Other)
);
ObjectExpressionAcc.ComputedProp.IgnoredInvalidNonLiteralKey)
| Named { name; _ } ->
let prop =
Field
Expand Down
2 changes: 1 addition & 1 deletion src/typing/type.ml
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,7 @@ module rec TypeTerm : sig
reason: reason;
reason_key: reason option;
value_t: t;
err_on_str_key: (use_op * reason) option;
err_on_str_key: use_op * reason;
}
| CheckReactImmutableT of {
lower_reason: reason;
Expand Down
20 changes: 13 additions & 7 deletions tests/numeric_keys/numeric_keys.exp
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,17 @@ References:

Error --------------------------------------------------------------------------------------- non_literal_number.js:12:6

Cannot use `n` [1] to assign a computed property. Only number literals are allowed, not `number` in general.
Cannot use number [1] to assign a computed property. Only number literals are allowed, not `number` in general.
[invalid-computed-prop]

non_literal_number.js:12:6
12| [n]: 1, // ERROR
^ [1]
^

References:
non_literal_number.js:10:20
10| declare const n: number;
^^^^^^ [1]


Error ------------------------------------------------------------------------------------------------------ test.js:8:3
Expand Down Expand Up @@ -620,7 +626,7 @@ Cannot access object with computed property using number [1]. Number literals mu

Error ---------------------------------------------------------------------------------------------------- test.js:188:6

Cannot use `1.1` [1] to assign a computed property. Only integer-like number literals are allowed.
Cannot use number [1] to assign a computed property. Only integer-like number literals are allowed.
[invalid-computed-prop]

188| [1.1]: true, // ERROR
Expand All @@ -629,17 +635,17 @@ Cannot use `1.1` [1] to assign a computed property. Only integer-like number lit

Error ---------------------------------------------------------------------------------------------------- test.js:189:6

Cannot use `9007199254740992` [1] to assign a computed property. Number literals must not be larger than
`Number.MAX_SAFE_INTEGER`. [invalid-computed-prop]
Cannot use number [1] to assign a computed property. Number literals must not be larger than `Number.MAX_SAFE_INTEGER`.
[invalid-computed-prop]

189| [9007199254740992]: false, // ERROR
^^^^^^^^^^^^^^^^ [1]


Error ---------------------------------------------------------------------------------------------------- test.js:190:6

Cannot use `-9007199254740992` [1] to assign a computed property. Number literals must not be smaller than
`Number.MIN_SAFE_INTEGER`. [invalid-computed-prop]
Cannot use number [1] to assign a computed property. Number literals must not be smaller than `Number.MIN_SAFE_INTEGER`.
[invalid-computed-prop]

190| [-9007199254740992]: false, // ERROR
^^^^^^^^^^^^^^^^^ [1]
Expand Down

0 comments on commit facff9a

Please sign in to comment.