Skip to content

Commit 24e1075

Browse files
avikchaudhurifacebook-github-bot
authored andcommitted
unary constant evaluation in types-first
Summary: We were careful to ask for annotations on addition and logical operations in signature verification, since Flow has complex logic for these operations, but forgot to do so for unary minus and not, where also the logic is complex. This diff compensates a bit in the signature generator, but there is still a gap between classic and types-first here. We can leave it as is by design, or do more later. Reviewed By: panagosg7 Differential Revision: D15565075 fbshipit-source-id: 014a7f05c004489f005bf2e047e4bb86df708023
1 parent 2aa42dd commit 24e1075

File tree

6 files changed

+63
-5
lines changed

6 files changed

+63
-5
lines changed

src/parser_utils/signature_builder_generate.ml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -975,18 +975,43 @@ module Eval(Env: Signature_builder_verify.EvalEnv) = struct
975975
end
976976
| _ -> None
977977

978-
and arith_unary operator loc _argument =
978+
and arith_unary operator loc argument =
979979
let open Ast.Expression.Unary in
980980
match operator with
981981
(* These operations have simple result types. *)
982-
| Minus -> loc, T.Number
983982
| Plus -> loc, T.Number
984-
| Not -> loc, T.Boolean
985983
| BitNot -> loc, T.Number
986984
| Typeof -> loc, T.String
987985
| Void -> loc, T.Void
988986
| Delete -> loc, T.Boolean
989987

988+
(* These operations may or may not have simple result types. See associated TODO: comment in
989+
Signature_builder_verify. *)
990+
| Minus ->
991+
begin match literal_expr argument with
992+
| _, T.NumberLiteral { Ast.NumberLiteral.value; raw } ->
993+
loc, T.NumberLiteral { Ast.NumberLiteral.value = -.value; raw = "-"^raw }
994+
| _ -> loc, T.Number
995+
end
996+
| Not ->
997+
begin match literal_expr argument with
998+
| _, T.BooleanLiteral b ->
999+
loc, T.BooleanLiteral (not b)
1000+
| _, T.Function _
1001+
| _, T.ObjectLiteral _
1002+
| _, T.ArrayLiteral _
1003+
| _, T.JSXLiteral _
1004+
-> loc, T.BooleanLiteral false
1005+
| _, T.Void
1006+
| _, T.Null
1007+
-> loc, T.BooleanLiteral true
1008+
| _, T.NumberLiteral { Ast.NumberLiteral.value; _ } ->
1009+
loc, T.BooleanLiteral (value = 0.)
1010+
| _, T.StringLiteral { Ast.StringLiteral.value; _ } ->
1011+
loc, T.BooleanLiteral (value = "")
1012+
| _ -> loc, T.Boolean
1013+
end
1014+
9901015
| Await ->
9911016
(* The result type of this operation depends in a complicated way on the argument type. *)
9921017
T.FixMe.mk_expr_type loc

src/parser_utils/signature_builder_verify.ml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,16 +420,21 @@ module Eval(Env: EvalEnv) = struct
420420
and arith_unary tps operator loc argument =
421421
let open Ast.Expression.Unary in
422422
match operator with
423-
| Minus
424423
| Plus
425-
| Not
426424
| BitNot
427425
| Typeof
428426
| Void
429427
| Delete
430428
->
431429
(* These operations have simple result types. *)
432430
ignore tps; ignore argument; Deps.bot
431+
| Minus
432+
| Not
433+
->
434+
(* TODO: These operations are evaluated by Flow; they may or may not have simple result
435+
types. Ideally we'd be verifying the argument. Unfortunately, we don't (see below). The
436+
generator does some basic constant evaluation to compensate, but it's not enough. *)
437+
ignore tps; ignore argument; Deps.bot
433438
| Await ->
434439
(* The result type of this operation depends in a complicated way on the argument type. *)
435440
Deps.top (Error.UnexpectedExpression (loc, Ast_utils.ExpressionSort.Unary))
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[options]
2+
experimental.well_formed_exports=true
3+
experimental.types_first=true

tests/types-first-unary/a.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @flow
2+
export type T1 = -1;
3+
export type T2 = false;
4+
export type T3 = 1;
5+
export type T4 = true;
6+
7+
module.exports = {
8+
P1: -1,
9+
P2: !true,
10+
P3: -(-1),
11+
P4: !!1,
12+
};

tests/types-first-unary/b.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @flow
2+
import type {
3+
T1,
4+
T2,
5+
T3,
6+
T4,
7+
} from './a';
8+
const A = require('./a');
9+
(A.P1: T1);
10+
(A.P2: T2);
11+
(A.P3: T3);
12+
(A.P4: T4);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Found 0 errors

0 commit comments

Comments
 (0)