From 0037b13927761d83037fe1df6da6e8be3bfec4cc Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Mon, 29 Nov 2021 13:45:48 -0800 Subject: [PATCH] feat(scope-manager): support TS4.5 import/export specifier kind --- .prettierignore | 9 +- .../src/referencer/ExportVisitor.ts | 7 +- .../tests/fixtures/export/default-type.ts | 1 + .../fixtures/export/default-type.ts.shot | 25 +++- .../tests/fixtures/export/type-inline.ts | 5 + .../tests/fixtures/export/type-inline.ts.shot | 75 ++++++++++++ .../fixtures/import/type-inline-value.ts | 5 + .../fixtures/import/type-inline-value.ts.shot | 74 ++++++++++++ .../tests/fixtures/import/type-inline.ts | 6 + .../tests/fixtures/import/type-inline.ts.shot | 109 ++++++++++++++++++ .../tests/fixtures/import/type-named.ts | 2 +- .../tests/fixtures/import/type-named.ts.shot | 8 +- .../type-declaration/literal-type1.ts | 4 +- .../type-declaration/literal-type2.ts | 5 +- .../type-declaration/literal-type3.ts | 8 +- 15 files changed, 320 insertions(+), 23 deletions(-) create mode 100644 packages/scope-manager/tests/fixtures/export/type-inline.ts create mode 100644 packages/scope-manager/tests/fixtures/export/type-inline.ts.shot create mode 100644 packages/scope-manager/tests/fixtures/import/type-inline-value.ts create mode 100644 packages/scope-manager/tests/fixtures/import/type-inline-value.ts.shot create mode 100644 packages/scope-manager/tests/fixtures/import/type-inline.ts create mode 100644 packages/scope-manager/tests/fixtures/import/type-inline.ts.shot diff --git a/.prettierignore b/.prettierignore index 8c4dce359d7a..92ec7008a80c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -20,8 +20,7 @@ packages/website/.docusaurus packages/website/build packages/website/src/vendor -# TODO - remove this once prettier supports TS4.1 -packages/scope-manager/tests/fixtures/type-declaration/literal-type1.ts -packages/scope-manager/tests/fixtures/type-declaration/literal-type2.ts -packages/scope-manager/tests/fixtures/type-declaration/literal-type3.ts -packages/scope-manager/tests/fixtures/type-declaration/mapped-named.ts +# TODO - remove this once prettier supports TS4.5 +packages/scope-manager/tests/fixtures/export/type-inline.ts +packages/scope-manager/tests/fixtures/import/type-inline.ts +packages/scope-manager/tests/fixtures/import/type-inline-value.ts diff --git a/packages/scope-manager/src/referencer/ExportVisitor.ts b/packages/scope-manager/src/referencer/ExportVisitor.ts index bae523ae6b21..0d542214b52b 100644 --- a/packages/scope-manager/src/referencer/ExportVisitor.ts +++ b/packages/scope-manager/src/referencer/ExportVisitor.ts @@ -65,7 +65,12 @@ class ExportVisitor extends Visitor { } protected ExportSpecifier(node: TSESTree.ExportSpecifier): void { - this.visit(node.local); + if (node.exportKind === 'type') { + // type export specifiers can only reference types + this.#referencer.currentScope().referenceType(node.local); + } else { + this.visit(node.local); + } } } diff --git a/packages/scope-manager/tests/fixtures/export/default-type.ts b/packages/scope-manager/tests/fixtures/export/default-type.ts index d62a0213891e..c49d502e4707 100644 --- a/packages/scope-manager/tests/fixtures/export/default-type.ts +++ b/packages/scope-manager/tests/fixtures/export/default-type.ts @@ -1,4 +1,5 @@ //// @sourceType = module +const T = 1; // unreferenced type T = 1; export default T; diff --git a/packages/scope-manager/tests/fixtures/export/default-type.ts.shot b/packages/scope-manager/tests/fixtures/export/default-type.ts.shot index cd8ffb388738..a03744ca6faf 100644 --- a/packages/scope-manager/tests/fixtures/export/default-type.ts.shot +++ b/packages/scope-manager/tests/fixtures/export/default-type.ts.shot @@ -6,14 +6,28 @@ ScopeManager { ImplicitGlobalConstTypeVariable, Variable$2 { defs: Array [ - TypeDefinition$1 { + VariableDefinition$1 { name: Identifier<"T">, - node: TSTypeAliasDeclaration$1, + node: VariableDeclarator$1, + }, + TypeDefinition$2 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$2, }, ], name: "T", references: Array [ Reference$1 { + identifier: Identifier<"T">, + init: true, + isRead: false, + isTypeReference: false, + isValueReference: true, + isWrite: true, + resolved: Variable$2, + writeExpr: Literal$3, + }, + Reference$2 { identifier: Identifier<"T">, isRead: true, isTypeReference: true, @@ -22,13 +36,13 @@ ScopeManager { resolved: Variable$2, }, ], - isValueVariable: false, + isValueVariable: true, isTypeVariable: true, }, ], scopes: Array [ GlobalScope$1 { - block: Program$2, + block: Program$4, isStrict: false, references: Array [], set: Map { @@ -41,10 +55,11 @@ ScopeManager { ], }, ModuleScope$2 { - block: Program$2, + block: Program$4, isStrict: true, references: Array [ Reference$1, + Reference$2, ], set: Map { "T" => Variable$2, diff --git a/packages/scope-manager/tests/fixtures/export/type-inline.ts b/packages/scope-manager/tests/fixtures/export/type-inline.ts new file mode 100644 index 000000000000..54016449936e --- /dev/null +++ b/packages/scope-manager/tests/fixtures/export/type-inline.ts @@ -0,0 +1,5 @@ +//// @sourceType = module + +const T = 1; // unreferenced +type T = 1; +export { type T }; diff --git a/packages/scope-manager/tests/fixtures/export/type-inline.ts.shot b/packages/scope-manager/tests/fixtures/export/type-inline.ts.shot new file mode 100644 index 000000000000..0463684b9638 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/export/type-inline.ts.shot @@ -0,0 +1,75 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`export type-inline 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + VariableDefinition$1 { + name: Identifier<"T">, + node: VariableDeclarator$1, + }, + TypeDefinition$2 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + init: true, + isRead: false, + isTypeReference: false, + isValueReference: true, + isWrite: true, + resolved: Variable$2, + writeExpr: Literal$3, + }, + Reference$2 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$4, + isStrict: false, + references: Array [], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + ], + }, + ModuleScope$2 { + block: Program$4, + isStrict: true, + references: Array [ + Reference$1, + Reference$2, + ], + set: Map { + "T" => Variable$2, + }, + type: "module", + upper: GlobalScope$1, + variables: Array [ + Variable$2, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/import/type-inline-value.ts b/packages/scope-manager/tests/fixtures/import/type-inline-value.ts new file mode 100644 index 000000000000..f6342cc28d07 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-inline-value.ts @@ -0,0 +1,5 @@ +//// @sourceType = module + +import {type foo} from 'foo'; + +type T = typeof foo; diff --git a/packages/scope-manager/tests/fixtures/import/type-inline-value.ts.shot b/packages/scope-manager/tests/fixtures/import/type-inline-value.ts.shot new file mode 100644 index 000000000000..037a97b96fc3 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-inline-value.ts.shot @@ -0,0 +1,74 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`import type-inline-value 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + ImportBindingDefinition$1 { + name: Identifier<"foo">, + node: ImportSpecifier$1, + }, + ], + name: "foo", + references: Array [ + Reference$1 { + identifier: Identifier<"foo">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "T", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + ], + }, + ModuleScope$2 { + block: Program$3, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "foo" => Variable$2, + "T" => Variable$3, + }, + type: "module", + upper: GlobalScope$1, + variables: Array [ + Variable$2, + Variable$3, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/import/type-inline.ts b/packages/scope-manager/tests/fixtures/import/type-inline.ts new file mode 100644 index 000000000000..28d0598c9036 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-inline.ts @@ -0,0 +1,6 @@ +//// @sourceType = module + +import {type T} from 'foo'; + +type Ref = T; +const unresolved = T; diff --git a/packages/scope-manager/tests/fixtures/import/type-inline.ts.shot b/packages/scope-manager/tests/fixtures/import/type-inline.ts.shot new file mode 100644 index 000000000000..4e5205e91d27 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/import/type-inline.ts.shot @@ -0,0 +1,109 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`import type-inline 1`] = ` +ScopeManager { + variables: Array [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: Array [ + ImportBindingDefinition$1 { + name: Identifier<"T">, + node: ImportSpecifier$1, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$2, + }, + Reference$3 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: false, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + TypeDefinition$2 { + name: Identifier<"Ref">, + node: TSTypeAliasDeclaration$2, + }, + ], + name: "Ref", + references: Array [], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$4 { + defs: Array [ + VariableDefinition$3 { + name: Identifier<"unresolved">, + node: VariableDeclarator$3, + }, + ], + name: "unresolved", + references: Array [ + Reference$2 { + identifier: Identifier<"unresolved">, + init: true, + isRead: false, + isTypeReference: false, + isValueReference: true, + isWrite: true, + resolved: Variable$4, + writeExpr: Identifier<"T">, + }, + ], + isValueVariable: true, + isTypeVariable: false, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$4, + isStrict: false, + references: Array [], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + }, + type: "global", + upper: null, + variables: Array [ + ImplicitGlobalConstTypeVariable, + ], + }, + ModuleScope$2 { + block: Program$4, + isStrict: true, + references: Array [ + Reference$1, + Reference$2, + Reference$3, + ], + set: Map { + "T" => Variable$2, + "Ref" => Variable$3, + "unresolved" => Variable$4, + }, + type: "module", + upper: GlobalScope$1, + variables: Array [ + Variable$2, + Variable$3, + Variable$4, + ], + }, + ], +} +`; diff --git a/packages/scope-manager/tests/fixtures/import/type-named.ts b/packages/scope-manager/tests/fixtures/import/type-named.ts index 1b73102379a1..f2d4b03083d9 100644 --- a/packages/scope-manager/tests/fixtures/import/type-named.ts +++ b/packages/scope-manager/tests/fixtures/import/type-named.ts @@ -3,4 +3,4 @@ import type { T } from 'foo'; type Ref = T; -const unresovled = T; +const unresolved = T; diff --git a/packages/scope-manager/tests/fixtures/import/type-named.ts.shot b/packages/scope-manager/tests/fixtures/import/type-named.ts.shot index ddf3bf95f63a..75b2214ff067 100644 --- a/packages/scope-manager/tests/fixtures/import/type-named.ts.shot +++ b/packages/scope-manager/tests/fixtures/import/type-named.ts.shot @@ -48,14 +48,14 @@ ScopeManager { Variable$4 { defs: Array [ VariableDefinition$3 { - name: Identifier<"unresovled">, + name: Identifier<"unresolved">, node: VariableDeclarator$3, }, ], - name: "unresovled", + name: "unresolved", references: Array [ Reference$2 { - identifier: Identifier<"unresovled">, + identifier: Identifier<"unresolved">, init: true, isRead: false, isTypeReference: false, @@ -94,7 +94,7 @@ ScopeManager { set: Map { "T" => Variable$2, "Ref" => Variable$3, - "unresovled" => Variable$4, + "unresolved" => Variable$4, }, type: "module", upper: GlobalScope$1, diff --git a/packages/scope-manager/tests/fixtures/type-declaration/literal-type1.ts b/packages/scope-manager/tests/fixtures/type-declaration/literal-type1.ts index 62d52177631d..3fe358428f70 100644 --- a/packages/scope-manager/tests/fixtures/type-declaration/literal-type1.ts +++ b/packages/scope-manager/tests/fixtures/type-declaration/literal-type1.ts @@ -1,3 +1,3 @@ -type Color = "red" | "blue"; -type Quantity = "one" | "two"; +type Color = 'red' | 'blue'; +type Quantity = 'one' | 'two'; type SeussFish = `${Quantity | Color} fish`; diff --git a/packages/scope-manager/tests/fixtures/type-declaration/literal-type2.ts b/packages/scope-manager/tests/fixtures/type-declaration/literal-type2.ts index b08b1843885d..264558bea382 100644 --- a/packages/scope-manager/tests/fixtures/type-declaration/literal-type2.ts +++ b/packages/scope-manager/tests/fixtures/type-declaration/literal-type2.ts @@ -1,2 +1,3 @@ -type EnthusiasticGreeting = `${Uppercase} - ${Lowercase} - ${Capitalize} - ${Uncapitalize}`; -type HELLO = EnthusiasticGreeting<"heLLo">; +type EnthusiasticGreeting = + `${Uppercase} - ${Lowercase} - ${Capitalize} - ${Uncapitalize}`; +type HELLO = EnthusiasticGreeting<'heLLo'>; diff --git a/packages/scope-manager/tests/fixtures/type-declaration/literal-type3.ts b/packages/scope-manager/tests/fixtures/type-declaration/literal-type3.ts index 126a004bf3e8..408889902ee8 100644 --- a/packages/scope-manager/tests/fixtures/type-declaration/literal-type3.ts +++ b/packages/scope-manager/tests/fixtures/type-declaration/literal-type3.ts @@ -1,8 +1,10 @@ -type VerticalAlignment = "top" | "middle" | "bottom"; -type HorizontalAlignment = "left" | "center" | "right"; +type VerticalAlignment = 'top' | 'middle' | 'bottom'; +type HorizontalAlignment = 'left' | 'center' | 'right'; // Takes // | "top-left" | "top-center" | "top-right" // | "middle-left" | "middle-center" | "middle-right" // | "bottom-left" | "bottom-center" | "bottom-right" -declare function setAlignment(value: `${VerticalAlignment}-${HorizontalAlignment}`): void; +declare function setAlignment( + value: `${VerticalAlignment}-${HorizontalAlignment}`, +): void;