-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flow] Scope analysis for
declare global {...}
Summary: This diff adds scope analysis for local checking of `declare global {...}`. Note that we don't have to do it for normal modules, since by the time we are checking normal modules, it will already have the extended globals injected into the context from type sig, so it doesn't have to read the globals from nested `declare global` block. For `declare global` within `declare module`, we special case it during scope analysis. We first hoist all the globals within declare global within the declare module, create a scope with it, and then create a scope for everything else. This will implement the scoping rule as described in D68246824. With this setup, we have the feature mostly working, and the only two issue remainings are globalThis interaction, and missing error for having value-decls within the declare global block. Changelog: [internal] Reviewed By: panagosg7 Differential Revision: D68851619 fbshipit-source-id: 1122ee2ec84fb0b6df6e7a3f47529ce3c2be6e50
- Loading branch information
1 parent
70c5bf1
commit 2f97af0
Showing
12 changed files
with
335 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[libs] | ||
react.js | ||
|
||
[options] | ||
all=true | ||
experimental.declare_global=true | ||
no_flowlib=false |
89 changes: 89 additions & 0 deletions
89
tests/declare_global_in_react_declare_module/declare_global_in_react_declare_module.exp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
Error --------------------------------------------------------------------------------------------------- react.js:10:10 | ||
|
||
Cannot redeclare global `React.Node` [1] because the global is already declared in another file. [name-already-bound] | ||
|
||
react.js:10:10 | ||
10| type React$Node = 1; // bad-shadow | ||
^^^^^^^^^^ | ||
|
||
References: | ||
<BUILTINS>/react.js:15:14 | ||
15| declare type React$Node = | ||
^^^^^^^^^^ [1] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:2:1 | ||
|
||
Cannot cast `2` to `React.Node` because number [1] is incompatible with number literal `1` [2]. [incompatible-cast] | ||
|
||
test.js:2:1 | ||
2| 2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
^ [1] | ||
|
||
References: | ||
test.js:2:6 | ||
2| 2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
^^^^^^^^^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:3:1 | ||
|
||
Cannot cast empty string to `MyReact` because string [1] is incompatible with string literal `react` [2]. | ||
[incompatible-cast] | ||
|
||
test.js:3:1 | ||
3| '' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
^^ [1] | ||
|
||
References: | ||
test.js:3:7 | ||
3| '' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
^^^^^^^^^^^^^^^^^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:4:1 | ||
|
||
Cannot resolve name `ReactValue`. [cannot-resolve-name] | ||
|
||
4| ReactValue; // error: value-namespaces in declare global are completely ignored | ||
^^^^^^^^^^ | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:5:1 | ||
|
||
Cannot resolve name `willBeIgnored`. [cannot-resolve-name] | ||
|
||
5| willBeIgnored; // error: values in declare global are completely ignored | ||
^^^^^^^^^^^^^ | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:8:1 | ||
|
||
Cannot cast empty string to `T1` because string [1] is incompatible with string literal `react` [2]. [incompatible-cast] | ||
|
||
test.js:8:1 | ||
8| '' as T1; // error: '' ~> 'react' | ||
^^ [1] | ||
|
||
References: | ||
test.js:8:7 | ||
8| '' as T1; // error: '' ~> 'react' | ||
^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:9:1 | ||
|
||
Cannot cast empty string to `T2` because string [1] is incompatible with number literal `3` [2]. [incompatible-cast] | ||
|
||
test.js:9:1 | ||
9| '' as T2 // error: '' ~> 3 | ||
^^ [1] | ||
|
||
References: | ||
test.js:9:7 | ||
9| '' as T2 // error: '' ~> 3 | ||
^^ [2] | ||
|
||
|
||
|
||
Found 7 errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
declare module 'react' { | ||
// $FlowExpectedError[undocumented-feature] | ||
declare global { | ||
declare namespace ReactTypes { | ||
type MyReact = 'react'; | ||
} | ||
declare namespace ReactValue { // TODO error: error on ignored value defs in declare global | ||
declare const willBeIgnored: string; | ||
} | ||
type React$Node = 1; // bad-shadow | ||
type ReactGlobalType = 3; | ||
declare const willBeIgnored: string; | ||
} | ||
|
||
export type T1 = ReactTypes.MyReact; | ||
export type T2 = ReactGlobalType; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// $FlowExpectedError[internal-type] | ||
2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
'' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
ReactValue; // error: value-namespaces in declare global are completely ignored | ||
willBeIgnored; // error: values in declare global are completely ignored | ||
|
||
import type {T1, T2} from 'react'; // test that the normal exported types can reference names within declare global | ||
'' as T1; // error: '' ~> 'react' | ||
'' as T2 // error: '' ~> 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
[options] | ||
all=true | ||
experimental.declare_global=true | ||
no_flowlib=false |
15 changes: 15 additions & 0 deletions
15
tests/declare_global_in_react_module/@flowtyped/react.js.flow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// $FlowExpectedError[undocumented-feature] | ||
declare global { | ||
declare namespace ReactTypes { | ||
type MyReact = 'react'; | ||
} | ||
declare namespace ReactValue { // TODO error: error on ignored value defs in declare global | ||
declare const willBeIgnored: string; | ||
} | ||
type React$Node = 1; // bad-shadow | ||
type ReactGlobalType = 3; | ||
declare const willBeIgnored: string; | ||
} | ||
|
||
export type T1 = ReactTypes.MyReact; | ||
export type T2 = ReactGlobalType; |
89 changes: 89 additions & 0 deletions
89
tests/declare_global_in_react_module/declare_global_in_react_module.exp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
Error ------------------------------------------------------------------------------------- @flowtyped/react.js.flow:9:8 | ||
|
||
Cannot redeclare global `React.Node` [1] because the global is already declared in another file. [name-already-bound] | ||
|
||
@flowtyped/react.js.flow:9:8 | ||
9| type React$Node = 1; // bad-shadow | ||
^^^^^^^^^^ | ||
|
||
References: | ||
<BUILTINS>/react.js:15:14 | ||
15| declare type React$Node = | ||
^^^^^^^^^^ [1] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:2:1 | ||
|
||
Cannot cast `2` to `React.Node` because number [1] is incompatible with number literal `1` [2]. [incompatible-cast] | ||
|
||
test.js:2:1 | ||
2| 2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
^ [1] | ||
|
||
References: | ||
test.js:2:6 | ||
2| 2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
^^^^^^^^^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:3:1 | ||
|
||
Cannot cast empty string to `MyReact` because string [1] is incompatible with string literal `react` [2]. | ||
[incompatible-cast] | ||
|
||
test.js:3:1 | ||
3| '' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
^^ [1] | ||
|
||
References: | ||
test.js:3:7 | ||
3| '' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
^^^^^^^^^^^^^^^^^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:4:1 | ||
|
||
Cannot resolve name `ReactValue`. [cannot-resolve-name] | ||
|
||
4| ReactValue; // error: value-namespaces in declare global are completely ignored | ||
^^^^^^^^^^ | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:5:1 | ||
|
||
Cannot resolve name `willBeIgnored`. [cannot-resolve-name] | ||
|
||
5| willBeIgnored; // error: values in declare global are completely ignored | ||
^^^^^^^^^^^^^ | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:8:1 | ||
|
||
Cannot cast empty string to `T1` because string [1] is incompatible with string literal `react` [2]. [incompatible-cast] | ||
|
||
test.js:8:1 | ||
8| '' as T1; // error: '' ~> 'react' | ||
^^ [1] | ||
|
||
References: | ||
test.js:8:7 | ||
8| '' as T1; // error: '' ~> 'react' | ||
^^ [2] | ||
|
||
|
||
Error ------------------------------------------------------------------------------------------------------ test.js:9:1 | ||
|
||
Cannot cast empty string to `T2` because string [1] is incompatible with number literal `3` [2]. [incompatible-cast] | ||
|
||
test.js:9:1 | ||
9| '' as T2 // error: '' ~> 3 | ||
^^ [1] | ||
|
||
References: | ||
test.js:9:7 | ||
9| '' as T2 // error: '' ~> 3 | ||
^^ [2] | ||
|
||
|
||
|
||
Found 7 errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// $FlowExpectedError[internal-type] | ||
2 as React$Node; // error: 2 ~> 1: The bad shadow wins over the real global. | ||
'' as ReactTypes.MyReact; // error: '' ~> 'react' | ||
ReactValue; // error: value-namespaces in declare global are completely ignored | ||
willBeIgnored; // error: values in declare global are completely ignored | ||
|
||
import type {T1, T2} from 'react'; // test that the normal exported types can reference names within declare global | ||
'' as T1; // error: '' ~> 'react' | ||
'' as T2 // error: '' ~> 3 |