From 20383733b033343e661f2e277bec947036ef764b Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 3 Jul 2021 17:43:44 +0800 Subject: [PATCH 1/3] fix: accept duplicated import/variable in different module both ts and flow fix #13510 --- .../input.js | 17 +++++++++++++++++ .../options.json | 3 +++ .../output.js | 15 +++++++++++++++ .../input.ts | 13 +++++++++++++ .../options.json | 4 ++++ .../output.mjs | 12 ++++++++++++ .../babel-types/src/validators/isBlockScoped.ts | 14 ++++++++++++-- 7 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/options.json create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/options.json create mode 100644 packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js new file mode 100644 index 000000000000..183abab3aa20 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js @@ -0,0 +1,17 @@ +// @flow + +declare module 'test' { + import type { JSONSchema7 } from 'json-schema'; + declare var a: number; + declare function foo(a: JSONSchema7): string; + declare export function concatPath(dirA: string, dirB: string): string; + declare export class A {} +} + +declare module 'test/submodule' { + import type { JSONSchema7 } from 'json-schema'; + declare var a: number; + declare function foo(a: JSONSchema7): string; + declare export function concatPath(dirA: string, dirB: string): string; + declare export class A {} +} diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/options.json b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/options.json new file mode 100644 index 000000000000..68e1a85e7d05 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["syntax-flow"] +} diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js new file mode 100644 index 000000000000..e22dc42f9d2e --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js @@ -0,0 +1,15 @@ +// @flow +declare module 'test' { + import type { JSONSchema7 } from 'json-schema'; + declare var a: number; + declare function foo(a: JSONSchema7): string; + declare export function concatPath(dirA: string, dirB: string): string; + declare export class A {} +} +declare module 'test/submodule' { + import type { JSONSchema7 } from 'json-schema'; + declare var a: number; + declare function foo(a: JSONSchema7): string; + declare export function concatPath(dirA: string, dirB: string): string; + declare export class A {} +} diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts new file mode 100644 index 000000000000..08aeff6f25ed --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts @@ -0,0 +1,13 @@ +declare module 'test' { + import type { JSONSchema7 } from 'json-schema'; + import { bar } from "baz"; + export { fooBar } from "baz"; + let foo: JSONSchema7; +} + +declare module 'test/submodule' { + import type { JSONSchema7 } from 'json-schema'; + import { bar } from "baz"; + export { fooBar } from "baz"; + let foo: JSONSchema7; +} diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/options.json b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/options.json new file mode 100644 index 000000000000..2e01a4468507 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/options.json @@ -0,0 +1,4 @@ +{ + "plugins": ["syntax-typescript"], + "sourceType": "module" +} diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs new file mode 100644 index 000000000000..9d555217b2a1 --- /dev/null +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs @@ -0,0 +1,12 @@ +declare module 'test' { + import type { JSONSchema7 } from 'json-schema'; + import { bar } from "baz"; + export { fooBar } from "baz"; + let foo: JSONSchema7; +} +declare module 'test/submodule' { + import type { JSONSchema7 } from 'json-schema'; + import { bar } from "baz"; + export { fooBar } from "baz"; + let foo: JSONSchema7; +} diff --git a/packages/babel-types/src/validators/isBlockScoped.ts b/packages/babel-types/src/validators/isBlockScoped.ts index 828963cf6165..8e97ceeddbe9 100644 --- a/packages/babel-types/src/validators/isBlockScoped.ts +++ b/packages/babel-types/src/validators/isBlockScoped.ts @@ -1,4 +1,8 @@ -import { isClassDeclaration, isFunctionDeclaration } from "./generated"; +import { + isClassDeclaration, + isFunctionDeclaration, + isImportDeclaration, +} from "./generated"; import isLet from "./isLet"; import type * as t from ".."; @@ -6,5 +10,11 @@ import type * as t from ".."; * Check if the input `node` is block scoped. */ export default function isBlockScoped(node: t.Node): boolean { - return isFunctionDeclaration(node) || isClassDeclaration(node) || isLet(node); + return ( + isFunctionDeclaration(node) || + isClassDeclaration(node) || + isLet(node) || + // import declaration can be block scoped when it's in TS/flow module declaration + isImportDeclaration(node) + ); } From 6b50ca57870dae814bef349fea99483a20aefa2e Mon Sep 17 00:00:00 2001 From: Colin Date: Tue, 6 Jul 2021 16:32:00 +0800 Subject: [PATCH 2/3] feat: use ImportDeclaration for ts/flow import inside module restore isBlockScoped validator --- packages/babel-traverse/src/scope/index.ts | 10 ++++++++++ .../input.js | 3 ++- .../output.js | 3 ++- .../input.ts | 3 +++ .../output.mjs | 5 ++++- .../babel-types/src/validators/isBlockScoped.ts | 14 ++------------ 6 files changed, 23 insertions(+), 15 deletions(-) diff --git a/packages/babel-traverse/src/scope/index.ts b/packages/babel-traverse/src/scope/index.ts index 98c7bc6a3884..9899ce22e1f2 100644 --- a/packages/babel-traverse/src/scope/index.ts +++ b/packages/babel-traverse/src/scope/index.ts @@ -202,6 +202,9 @@ const collectorVisitor: Visitor = { // delegate block scope handling to the `BlockScoped` method if (path.isBlockScoped()) return; + // import handing to the `ImportDeclaration` method + if (path.isImportDeclaration()) return; + // this will be hit again once we traverse into it after this iteration if (path.isExportDeclaration()) return; @@ -211,6 +214,13 @@ const collectorVisitor: Visitor = { parent.registerDeclaration(path); }, + ImportDeclaration(path) { + // import may only appear in the top level or inside a module/namespace (for TS/flow) + const parent = path.scope.getBlockParent(); + + parent.registerDeclaration(path); + }, + ReferencedIdentifier(path, state) { state.references.push(path); }, diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js index 183abab3aa20..2b62c754ba4e 100644 --- a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/input.js @@ -1,10 +1,11 @@ // @flow +type T = string; declare module 'test' { import type { JSONSchema7 } from 'json-schema'; declare var a: number; declare function foo(a: JSONSchema7): string; - declare export function concatPath(dirA: string, dirB: string): string; + declare export function concatPath(dirA: string, dirB: T): string; declare export class A {} } diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js index e22dc42f9d2e..2c53a4cc6712 100644 --- a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-flow/output.js @@ -1,9 +1,10 @@ // @flow +type T = string; declare module 'test' { import type { JSONSchema7 } from 'json-schema'; declare var a: number; declare function foo(a: JSONSchema7): string; - declare export function concatPath(dirA: string, dirB: string): string; + declare export function concatPath(dirA: string, dirB: T): string; declare export class A {} } declare module 'test/submodule' { diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts index 08aeff6f25ed..c592c6cb3ed4 100644 --- a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/input.ts @@ -1,8 +1,11 @@ +type T = number; declare module 'test' { import type { JSONSchema7 } from 'json-schema'; import { bar } from "baz"; export { fooBar } from "baz"; let foo: JSONSchema7; + // can reference type outsider module + let baz: T; } declare module 'test/submodule' { diff --git a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs index 9d555217b2a1..ef3bc38db90f 100644 --- a/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs +++ b/packages/babel-traverse/test/fixtures/regression/duplicate-variable-in-different-module-ts/output.mjs @@ -1,8 +1,11 @@ +type T = number; declare module 'test' { import type { JSONSchema7 } from 'json-schema'; import { bar } from "baz"; export { fooBar } from "baz"; - let foo: JSONSchema7; + let foo: JSONSchema7; // can reference type outsider module + + let baz: T; } declare module 'test/submodule' { import type { JSONSchema7 } from 'json-schema'; diff --git a/packages/babel-types/src/validators/isBlockScoped.ts b/packages/babel-types/src/validators/isBlockScoped.ts index 8e97ceeddbe9..828963cf6165 100644 --- a/packages/babel-types/src/validators/isBlockScoped.ts +++ b/packages/babel-types/src/validators/isBlockScoped.ts @@ -1,8 +1,4 @@ -import { - isClassDeclaration, - isFunctionDeclaration, - isImportDeclaration, -} from "./generated"; +import { isClassDeclaration, isFunctionDeclaration } from "./generated"; import isLet from "./isLet"; import type * as t from ".."; @@ -10,11 +6,5 @@ import type * as t from ".."; * Check if the input `node` is block scoped. */ export default function isBlockScoped(node: t.Node): boolean { - return ( - isFunctionDeclaration(node) || - isClassDeclaration(node) || - isLet(node) || - // import declaration can be block scoped when it's in TS/flow module declaration - isImportDeclaration(node) - ); + return isFunctionDeclaration(node) || isClassDeclaration(node) || isLet(node); } From 4f1c80269a7946e70a3e5132f645322c7f5d53b9 Mon Sep 17 00:00:00 2001 From: Colin Wang Date: Tue, 6 Jul 2021 21:38:00 +0800 Subject: [PATCH 3/3] Update packages/babel-traverse/src/scope/index.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Huáng Jùnliàng --- packages/babel-traverse/src/scope/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-traverse/src/scope/index.ts b/packages/babel-traverse/src/scope/index.ts index 9899ce22e1f2..c77a0b3e8adc 100644 --- a/packages/babel-traverse/src/scope/index.ts +++ b/packages/babel-traverse/src/scope/index.ts @@ -202,7 +202,7 @@ const collectorVisitor: Visitor = { // delegate block scope handling to the `BlockScoped` method if (path.isBlockScoped()) return; - // import handing to the `ImportDeclaration` method + // delegate import handing to the `ImportDeclaration` method if (path.isImportDeclaration()) return; // this will be hit again once we traverse into it after this iteration