Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BigInt typechecking #7602

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c9c3879
[common] Add BigNum printers
goodmind Mar 31, 2019
42a681d
[services] Add BigNum cases to autocomplete
goodmind Mar 31, 2019
a385d66
[typing] Add BigNumT constructor
goodmind Mar 31, 2019
cc848d4
[typing] add typeof "bigint" check
goodmind Mar 31, 2019
1d98730
[typing] Add BigInt operations
goodmind Mar 31, 2019
0e1b2eb
[typing] Add sketchy-null-bigint check
goodmind Mar 31, 2019
974a51e
[newtests] Add sketchy-null-bigint tests
goodmind Mar 31, 2019
4738172
[typing] Add comparison for BigInt
goodmind Apr 1, 2019
92b26ac
[tests] Add BigInt to arith test
goodmind Apr 1, 2019
3b3f7ab
[website] Add docs about BigInt lint rules
goodmind Apr 2, 2019
cdde41b
[newtests] Update bigint test
goodmind Apr 2, 2019
2f3d389
[common] rename BigNum to BigInt
goodmind May 9, 2019
86b3b31
[typing] rename BIgNumT to BigIntT
goodmind May 9, 2019
df998dc
[services] rename BigNumLit to BigIntLit
goodmind May 9, 2019
a54ea43
[tests] rename BigNumT to BigIntT
goodmind May 9, 2019
ab4aea4
[tests] Update arith snapshot
goodmind Jun 7, 2019
a01d9bb
[typing] Add missing bigint assert match
goodmind Jun 7, 2019
9fa715b
[typing] Specify Bottom argument to EmptyT
goodmind Jun 7, 2019
07c4a64
[typing] Add TODOs to update and op_assignment
goodmind Jun 7, 2019
bb7b2b0
[typing] Generalize AdderT to ArithmeticBInaryT and ArithmeticUnaryT
goodmind Jul 10, 2019
fc35e3d
[tests] Update arith tests
goodmind Jul 10, 2019
a902843
[typing] Add missing BigInt and BigIntLit
goodmind Jul 10, 2019
6447652
[typing] Add context to mk_singleton_bigint
goodmind Jul 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 1 addition & 150 deletions newtests/bigint/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,156 +201,7 @@ export default suite(({ addFile, addFiles, addCode }) => [
const valid_neg_small = -100n;
type ValidSmall = 100n;
type ValidNegSmall = -1n;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests for BigInts with numeric separators are missing here. Parser already support them.

`).newErrors(
`
test.js:4
4: type S = bigint;
^^^^^^ BigInt bigint [1] is not yet supported.
References:
4: type S = bigint;
^^^^^^ [1]

test.js:6
6: const valid_binary = 0b101011101n;
^^^^^^^^^^^^ BigInt bigint literal \`0b101011101n\` [1] is not yet supported.
References:
6: const valid_binary = 0b101011101n;
^^^^^^^^^^^^ [1]

test.js:7
7: const valid_neg_binary = -0b101011101n;
^^^^^^^^^^^^ BigInt bigint literal \`0b101011101n\` [1] is not yet supported.
References:
7: const valid_neg_binary = -0b101011101n;
^^^^^^^^^^^^ [1]

test.js:8
8: type ValidBinary = 0b101011101n;
^^^^^^^^^^^^ BigInt bigint literal \`0b101011101n\` [1] is not yet supported.
References:
8: type ValidBinary = 0b101011101n;
^^^^^^^^^^^^ [1]

test.js:9
9: type ValidNegBinary = -0b101011101n;
^^^^^^^^^^^^^ BigInt bigint literal \`-0b101011101n\` [1] is not yet supported.
References:
9: type ValidNegBinary = -0b101011101n;
^^^^^^^^^^^^^ [1]

test.js:11
11: const valid_hex = 0xfff123n;
^^^^^^^^^ BigInt bigint literal \`0xfff123n\` [1] is not yet supported.
References:
11: const valid_hex = 0xfff123n;
^^^^^^^^^ [1]

test.js:12
12: const valid_neg_hex = -0xfff123n;
^^^^^^^^^ BigInt bigint literal \`0xfff123n\` [1] is not yet supported.
References:
12: const valid_neg_hex = -0xfff123n;
^^^^^^^^^ [1]

test.js:13
13: type ValidHex = 0xfff123n;
^^^^^^^^^ BigInt bigint literal \`0xfff123n\` [1] is not yet supported.
References:
13: type ValidHex = 0xfff123n;
^^^^^^^^^ [1]

test.js:14
14: type ValidNegHex = -0xfff123n;
^^^^^^^^^^ BigInt bigint literal \`-0xfff123n\` [1] is not yet supported.
References:
14: type ValidNegHex = -0xfff123n;
^^^^^^^^^^ [1]

test.js:16
16: const valid_large = 9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ BigInt bigint literal \`9223372036854775807n\` [1] is not yet supported.
References:
16: const valid_large = 9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ [1]

test.js:17
17: const valid_neg_large = -9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ BigInt bigint literal \`9223372036854775807n\` [1] is not yet supported.
References:
17: const valid_neg_large = -9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ [1]

test.js:18
18: type ValidLarge = 9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ BigInt bigint literal \`9223372036854775807n\` [1] is not yet supported.
References:
18: type ValidLarge = 9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^ [1]

test.js:19
19: type ValidNegLarge = -9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^^ BigInt bigint literal \`-9223372036854775807n\` [1] is not yet supported.
References:
19: type ValidNegLarge = -9223372036854775807n;
^^^^^^^^^^^^^^^^^^^^^ [1]

test.js:21
21: const valid_octal_new = 0o16432n;
^^^^^^^^ BigInt bigint literal \`0o16432n\` [1] is not yet supported.
References:
21: const valid_octal_new = 0o16432n;
^^^^^^^^ [1]

test.js:22
22: const valid_neg_octal_new = -0o16432n;
^^^^^^^^ BigInt bigint literal \`0o16432n\` [1] is not yet supported.
References:
22: const valid_neg_octal_new = -0o16432n;
^^^^^^^^ [1]

test.js:23
23: type ValidOctalNew = 0o16432n;
^^^^^^^^ BigInt bigint literal \`0o16432n\` [1] is not yet supported.
References:
23: type ValidOctalNew = 0o16432n;
^^^^^^^^ [1]

test.js:24
24: type ValidNegOctalNew = -0o16432n;
^^^^^^^^^ BigInt bigint literal \`-0o16432n\` [1] is not yet supported.
References:
24: type ValidNegOctalNew = -0o16432n;
^^^^^^^^^ [1]

test.js:26
26: const valid_small = 100n;
^^^^ BigInt bigint literal \`100n\` [1] is not yet supported.
References:
26: const valid_small = 100n;
^^^^ [1]

test.js:27
27: const valid_neg_small = -100n;
^^^^ BigInt bigint literal \`100n\` [1] is not yet supported.
References:
27: const valid_neg_small = -100n;
^^^^ [1]

test.js:28
28: type ValidSmall = 100n;
^^^^ BigInt bigint literal \`100n\` [1] is not yet supported.
References:
28: type ValidSmall = 100n;
^^^^ [1]

test.js:29
29: type ValidNegSmall = -1n;
^^^ BigInt bigint literal \`-1n\` [1] is not yet supported.
References:
29: type ValidNegSmall = -1n;
^^^ [1]
`,
)
`).noNewErrors()
]),

test("BigInt can be suppressed", [
Expand Down
3 changes: 3 additions & 0 deletions newtests/sketchy_null/flowSketchyFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ function printSketchyBoolean(sketch: NullableType): void {
if (sketch.nullableStr) {
console.log(sketch.nullableStr);
}
if (sketch.nullableBigInt) {
console.log(sketch.nullableBigInt);
}
}
9 changes: 9 additions & 0 deletions newtests/sketchy_null/flowStrictSketchyBigIntFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @flow strict

import type { NullableBigInt } from './flowTypeFile';

function printSketchyNumber(sketch: NullableBigInt): void {
if (sketch.nullableBigInt) {
console.log(sketch.nullableBigInt);
}
}
1 change: 1 addition & 0 deletions newtests/sketchy_null/flowStrictTypeFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export type NullableType = {
nullableStr?: string,
nullableNum?: number,
nullableBool?: boolean,
nullableBigInt?: bigint,
};
4 changes: 4 additions & 0 deletions newtests/sketchy_null/flowTypeFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ export type NullableNumber = {
export type NullableBool = {
nullableBool?: boolean,
};

export type NullableBigInt = {
nullableBigInt?: bigint,
};
13 changes: 13 additions & 0 deletions newtests/sketchy_null/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ export default suite(({addFiles, addCode, flowCmd}) => [
`,
).exitCodes([]),
]),
test('should trigger sketchy null output on sketchy bigint', [
addFiles('flowTypeFile.js', 'flowStrictSketchyBigIntFile.js')
.newErrors(
`
flowStrictSketchyBigIntFile.js:6
6: if (sketch.nullableBigInt) {
^^^^^^^^^^^^^^^^^^^^^ Sketchy null check on bigint [1] which is potentially 0n. Perhaps you meant to check for null or undefined [1]? (\`sketchy-null-bigint\`)
References:
16: nullableBigInt?: bigint,
^^^^^^ [1]. See: flowTypeFile.js:16
`,
).exitCodes([]),
]),
test('should trigger sketchy null output on sketchy bool', [
addFiles('flowTypeFile.js', 'flowStrictSketchyBooleanFile.js')
.newErrors(
Expand Down
4 changes: 4 additions & 0 deletions src/common/lints/lints.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type sketchy_null_kind =
| SketchyNullBool
| SketchyNullString
| SketchyNullNumber
| SketchyNullBigInt
| SketchyNullMixed

type sketchy_number_kind =
Expand Down Expand Up @@ -37,6 +38,7 @@ let string_of_sketchy_null_kind = function
| SketchyNullBool -> "sketchy-null-bool"
| SketchyNullString -> "sketchy-null-string"
| SketchyNullNumber -> "sketchy-null-number"
| SketchyNullBigInt -> "sketchy-null-bigint"
| SketchyNullMixed -> "sketchy-null-mixed"

let string_of_sketchy_number_kind = function
Expand Down Expand Up @@ -66,11 +68,13 @@ let kinds_of_string = function
SketchyNull SketchyNullBool;
SketchyNull SketchyNullString;
SketchyNull SketchyNullNumber;
SketchyNull SketchyNullBigInt;
SketchyNull SketchyNullMixed;
]
| "sketchy-null-bool" -> Some [SketchyNull SketchyNullBool]
| "sketchy-null-string" -> Some [SketchyNull SketchyNullString]
| "sketchy-null-number" -> Some [SketchyNull SketchyNullNumber]
| "sketchy-null-bigint" -> Some [SketchyNull SketchyNullBigInt]
| "sketchy-null-mixed" -> Some [SketchyNull SketchyNullMixed]
| "sketchy-number" -> Some [
SketchyNumber SketchyNumberAnd;
Expand Down
1 change: 1 addition & 0 deletions src/common/lints/lints.mli
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type sketchy_null_kind =
| SketchyNullBool
| SketchyNullString
| SketchyNullNumber
| SketchyNullBigInt
| SketchyNullMixed

type sketchy_number_kind =
Expand Down
4 changes: 3 additions & 1 deletion src/common/ty/ty.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ type t =
| Bot of bot_kind
| Void | Null
| Num of string option
| BigInt of string option
| Str of string option
| Bool of bool option
| NumLit of string
| BigIntLit of string
| StrLit of string
| BoolLit of bool
| Fun of fun_t
Expand Down Expand Up @@ -257,7 +259,7 @@ let rec mk_exact ty =
| Mu (i, t) -> Mu (i, mk_exact t)
(* Not applicable *)
| Any _ | Top | Bot _ | Void | Null
| Num _ | Str _ | Bool _ | NumLit _ | StrLit _ | BoolLit _
| Num _ | BigInt _ | Str _ | Bool _ | NumLit _ | BigIntLit _ | StrLit _ | BoolLit _
| Fun _ | Arr _ | Tup _ -> ty
(* Do not nest $Exact *)
| Utility (Exact _) -> ty
Expand Down
8 changes: 7 additions & 1 deletion src/common/ty/ty_debug.ml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ and dump_t ?(depth = 10) t =
| Num (Some x) -> spf "Num (%s)" x
| Num None -> "Num"
| NumLit s -> spf "\"%s\"" s
| BigInt (Some x) -> spf "BigInt (%s)" x
| BigInt None -> "BigInt"
| BigIntLit s -> spf "\"%s\"" s
| Str (Some x) -> spf "Str (%s)" x
| Str None -> "Str"
| StrLit s -> spf "\"%s\"" s
Expand Down Expand Up @@ -205,9 +208,11 @@ let string_of_ctor = function
| Void -> "Void"
| Null -> "Null"
| Num _ -> "Num"
| BigInt _ -> "BigInt"
| Str _ -> "Str"
| Bool _ -> "Bool"
| NumLit _ -> "NumLit"
| BigIntLit _ -> "BigIntLit"
| StrLit _ -> "StrLit"
| BoolLit _ -> "BoolLit"
| Fun _ -> "Fun"
Expand Down Expand Up @@ -258,8 +263,9 @@ let json_of_t ~strip_root =
| Any Explicit -> [ "any", JSON_String "explicit" ]
| Top | Bot _
| Void | Null
| Num _ | Str _ | Bool _ -> []
| Num _ | BigInt _ | Str _ | Bool _ -> []
| NumLit s
| BigIntLit s
| StrLit s -> [
"literal", JSON_String s
]
Expand Down
2 changes: 2 additions & 0 deletions src/common/ty/ty_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ let type_ ?(size=5000) ?(with_comments=true) t =
| Void -> Atom "void"
| Null -> Atom "null"
| Num _ -> Atom "number"
| BigInt _ -> Atom "bigint"
| Str _ -> Atom "string"
| Bool _ -> Atom "boolean"
| Fun func ->
Expand All @@ -103,6 +104,7 @@ let type_ ?(size=5000) ?(with_comments=true) t =
(counted_map (type_ ~depth) ts)
| StrLit raw -> fuse (in_quotes raw)
| NumLit raw -> Atom raw
| BigIntLit raw -> Atom raw
| BoolLit value -> Atom (if value then "true" else "false")
| TypeAlias ta -> type_alias ta
| TypeOf (path, name) ->
Expand Down
11 changes: 11 additions & 0 deletions src/common/ty/ty_serializer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ let rec type_ t =
return (builtin_from_string "$TEMPORARY$number"
~targs:(Loc.none, [Loc.none, T.NumberLiteral (num_lit lit)]))
| Num None -> just T.Number
| BigInt (Some lit) ->
return (builtin_from_string "$TEMPORARY$bigint"
~targs:(Loc.none, [Loc.none, T.BigIntLiteral (bignum_lit lit)]))
| BigInt None -> just T.BigInt
| Str (Some lit) ->
return (builtin_from_string "$TEMPORARY$string"
~targs:(Loc.none, [Loc.none, T.StringLiteral (str_lit lit)]))
Expand All @@ -68,6 +72,7 @@ let rec type_ t =
~targs:(Loc.none, [Loc.none, (T.BooleanLiteral lit)]))
| Bool None -> just T.Boolean
| NumLit lit -> just (T.NumberLiteral (num_lit lit))
| BigIntLit lit -> just (T.BigIntLiteral (bignum_lit lit))
| StrLit lit -> just (T.StringLiteral (str_lit lit))
| BoolLit lit -> just (T.BooleanLiteral lit)
| Fun f -> function_ f >>| fun f -> (Loc.none, T.Function f)
Expand Down Expand Up @@ -279,6 +284,12 @@ and num_lit lit = {
raw = lit;
}

and bignum_lit lit = {
Ast.BigIntLiteral.
approx_value = (try Pervasives.float_of_string lit with Failure _ -> 0.);
bigint = lit;
}

and getter t = function_ {
fun_params = [];
fun_rest_param = None;
Expand Down
4 changes: 2 additions & 2 deletions src/services/autocomplete/autocompleteService_js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ let lsp_completion_of_type (ty: Ty.t) =
match ty with
| Ty.InterfaceDecl _ -> Some Interface
| Ty.ClassDecl _ -> Some Class
| Ty.(StrLit _ | NumLit _ | BoolLit _) -> Some Value
| Ty.(StrLit _ | NumLit _ | BigIntLit _ | BoolLit _) -> Some Value
| Ty.Fun _ -> Some Function
| Ty.TypeAlias _
| Ty.Union _ -> Some Enum
| Ty.Module _ -> Some Module
| Ty.(Tup _ | Bot _ | Null | Obj _ | Inter _ | TVar _ | Bound _ | Generic _ |
Any _ | Top | Void | Num _ | Str _ | Bool _ | Arr _ | TypeOf _ |
Any _ | Top | Void | Num _ | BigInt _ | Str _ | Bool _ | Arr _ | TypeOf _ |
Utility _ | Mu _
) -> Some Variable

Expand Down
2 changes: 2 additions & 0 deletions src/typing/coverage.ml
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,12 @@ class visitor = object (self)
| DefT (_, t, IdxWrapper _)
| DefT (_, t, MixedT _)
| DefT (_, t, NumT _)
| DefT (_, t, BigIntT _)
| DefT (_, t, NullT)
| DefT (_, t, ObjT _)
| DefT (_, t, ReactAbstractComponentT _)
| DefT (_, t, SingletonNumT _)
| DefT (_, t, SingletonBigIntT _)
| DefT (_, t, SingletonStrT _)
| DefT (_, t, SingletonBoolT _)
| DefT (_, t, StrT _)
Expand Down
Loading