From cbab0e578096f50ced40534d4c205978702ac148 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Fri, 23 Dec 2022 23:53:56 -0500 Subject: [PATCH 1/2] fix(typescript-estree): account for nested namespace nesting in AST conversion --- .../snapshots/1-TSESTree-AST.shot | 54 ++--------- .../snapshots/5-AST-Alignment-AST.shot | 91 +++++++++++++++++- .../snapshots/1-TSESTree-AST.shot | 54 ++--------- .../snapshots/5-AST-Alignment-AST.shot | 91 +++++++++++++++++- .../fixtures/namespace-nested-once/fixture.ts | 1 + .../snapshots/1-TSESTree-AST.shot | 45 +++++++++ .../snapshots/2-TSESTree-Tokens.shot | 66 +++++++++++++ .../snapshots/3-Babel-AST.shot | 64 +++++++++++++ .../snapshots/4-Babel-Tokens.shot | 66 +++++++++++++ .../snapshots/5-AST-Alignment-AST.shot | 76 +++++++++++++++ .../snapshots/6-AST-Alignment-Tokens.shot | 6 ++ .../namespace-nested-twice/fixture.ts | 1 + .../snapshots/1-TSESTree-AST.shot | 45 +++++++++ .../snapshots/2-TSESTree-Tokens.shot | 86 +++++++++++++++++ .../snapshots/3-Babel-AST.shot | 83 ++++++++++++++++ .../snapshots/4-Babel-Tokens.shot | 86 +++++++++++++++++ .../snapshots/5-AST-Alignment-AST.shot | 95 +++++++++++++++++++ .../snapshots/6-AST-Alignment-Tokens.shot | 6 ++ .../tests/fixtures-with-differences-ast.shot | 4 + packages/typescript-estree/src/convert.ts | 50 ++++++++-- 20 files changed, 967 insertions(+), 103 deletions(-) create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/fixture.ts create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/2-TSESTree-Tokens.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/3-Babel-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/4-Babel-Tokens.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/6-AST-Alignment-Tokens.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/fixture.ts create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/2-TSESTree-Tokens.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/3-Babel-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/4-Babel-Tokens.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot create mode 100644 packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/6-AST-Alignment-Tokens.shot diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot index 3dfc069dda7e..df20691d205f 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot @@ -6,62 +6,24 @@ Program { body: Array [ TSModuleDeclaration { type: "TSModuleDeclaration", - body: TSModuleDeclaration { - type: "TSModuleDeclaration", - body: TSModuleDeclaration { - type: "TSModuleDeclaration", - body: TSModuleBlock { - type: "TSModuleBlock", - body: Array [], + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], - range: [13, 15], - loc: { - start: { column: 13, line: 1 }, - end: { column: 15, line: 1 }, - }, - }, - id: Identifier { - type: "Identifier", - name: "C", - - range: [11, 12], - loc: { - start: { column: 11, line: 1 }, - end: { column: 12, line: 1 }, - }, - }, - - range: [11, 15], - loc: { - start: { column: 11, line: 1 }, - end: { column: 15, line: 1 }, - }, - }, - id: Identifier { - type: "Identifier", - name: "B", - - range: [9, 10], - loc: { - start: { column: 9, line: 1 }, - end: { column: 10, line: 1 }, - }, - }, - - range: [9, 15], + range: [13, 15], loc: { - start: { column: 9, line: 1 }, + start: { column: 13, line: 1 }, end: { column: 15, line: 1 }, }, }, id: Identifier { type: "Identifier", - name: "A", + name: "A.B.C", - range: [7, 8], + range: [7, 12], loc: { start: { column: 7, line: 1 }, - end: { column: 8, line: 1 }, + end: { column: 12, line: 1 }, }, }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot index d442f261db29..344f8c6d4f16 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot @@ -2,5 +2,94 @@ exports[`AST Fixtures declaration TSModuleDeclaration module-id-qualified-name AST Alignment - AST 1`] = ` "Snapshot Diff: -Compared values have no visual difference." +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + TSModuleDeclaration { + type: 'TSModuleDeclaration', +- body: TSModuleBlock { +- type: 'TSModuleBlock', +- body: Array [], ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleBlock { ++ type: 'TSModuleBlock', ++ body: Array [], ++ ++ range: [13, 15], ++ loc: { ++ start: { column: 13, line: 1 }, ++ end: { column: 15, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'C', + +- range: [13, 15], ++ range: [11, 12], ++ loc: { ++ start: { column: 11, line: 1 }, ++ end: { column: 12, line: 1 }, ++ }, ++ }, ++ ++ range: [11, 15], ++ loc: { ++ start: { column: 11, line: 1 }, ++ end: { column: 15, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'B', ++ ++ range: [9, 10], ++ loc: { ++ start: { column: 9, line: 1 }, ++ end: { column: 10, line: 1 }, ++ }, ++ }, ++ ++ range: [9, 15], + loc: { +- start: { column: 13, line: 1 }, ++ start: { column: 9, line: 1 }, + end: { column: 15, line: 1 }, + }, + }, + id: Identifier { + type: 'Identifier', +- name: 'A.B.C', ++ name: 'A', + +- range: [7, 12], ++ range: [7, 8], + loc: { + start: { column: 7, line: 1 }, +- end: { column: 12, line: 1 }, ++ end: { column: 8, line: 1 }, + }, + }, + + range: [0, 15], + loc: { + start: { column: 0, line: 1 }, + end: { column: 15, line: 1 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 16], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, + }" `; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot index 98cd5bbe8176..03da1caa8b3c 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot @@ -6,62 +6,24 @@ Program { body: Array [ TSModuleDeclaration { type: "TSModuleDeclaration", - body: TSModuleDeclaration { - type: "TSModuleDeclaration", - body: TSModuleDeclaration { - type: "TSModuleDeclaration", - body: TSModuleBlock { - type: "TSModuleBlock", - body: Array [], + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], - range: [16, 18], - loc: { - start: { column: 16, line: 1 }, - end: { column: 18, line: 1 }, - }, - }, - id: Identifier { - type: "Identifier", - name: "C", - - range: [14, 15], - loc: { - start: { column: 14, line: 1 }, - end: { column: 15, line: 1 }, - }, - }, - - range: [14, 18], - loc: { - start: { column: 14, line: 1 }, - end: { column: 18, line: 1 }, - }, - }, - id: Identifier { - type: "Identifier", - name: "B", - - range: [12, 13], - loc: { - start: { column: 12, line: 1 }, - end: { column: 13, line: 1 }, - }, - }, - - range: [12, 18], + range: [16, 18], loc: { - start: { column: 12, line: 1 }, + start: { column: 16, line: 1 }, end: { column: 18, line: 1 }, }, }, id: Identifier { type: "Identifier", - name: "A", + name: "A.B.C", - range: [10, 11], + range: [10, 15], loc: { start: { column: 10, line: 1 }, - end: { column: 11, line: 1 }, + end: { column: 15, line: 1 }, }, }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot index a7a16eee58a5..cc5a251b954d 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot @@ -2,5 +2,94 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-id-qualified-name AST Alignment - AST 1`] = ` "Snapshot Diff: -Compared values have no visual difference." +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + TSModuleDeclaration { + type: 'TSModuleDeclaration', +- body: TSModuleBlock { +- type: 'TSModuleBlock', +- body: Array [], ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleBlock { ++ type: 'TSModuleBlock', ++ body: Array [], ++ ++ range: [16, 18], ++ loc: { ++ start: { column: 16, line: 1 }, ++ end: { column: 18, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'C', + +- range: [16, 18], ++ range: [14, 15], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 15, line: 1 }, ++ }, ++ }, ++ ++ range: [14, 18], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 18, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'B', ++ ++ range: [12, 13], ++ loc: { ++ start: { column: 12, line: 1 }, ++ end: { column: 13, line: 1 }, ++ }, ++ }, ++ ++ range: [12, 18], + loc: { +- start: { column: 16, line: 1 }, ++ start: { column: 12, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + id: Identifier { + type: 'Identifier', +- name: 'A.B.C', ++ name: 'A', + +- range: [10, 15], ++ range: [10, 11], + loc: { + start: { column: 10, line: 1 }, +- end: { column: 15, line: 1 }, ++ end: { column: 11, line: 1 }, + }, + }, + + range: [0, 18], + loc: { + start: { column: 0, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 19], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, + }" `; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/fixture.ts b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/fixture.ts new file mode 100644 index 000000000000..e4db463ec8fe --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/fixture.ts @@ -0,0 +1 @@ +namespace abd.def {} diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot new file mode 100644 index 000000000000..e4cd973cb92d --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once TSESTree - AST 1`] = ` +Program { + type: "Program", + body: Array [ + TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], + + range: [18, 20], + loc: { + start: { column: 18, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "abd.def", + + range: [10, 17], + loc: { + start: { column: 10, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + + range: [0, 20], + loc: { + start: { column: 0, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + ], + sourceType: "script", + + range: [0, 21], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, +} +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/2-TSESTree-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/2-TSESTree-Tokens.shot new file mode 100644 index 000000000000..23c1cc3f1ace --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/2-TSESTree-Tokens.shot @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once TSESTree - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "namespace", + + range: [0, 9], + loc: { + start: { column: 0, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abd", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [13, 14], + loc: { + start: { column: 13, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [18, 19], + loc: { + start: { column: 18, line: 1 }, + end: { column: 19, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [19, 20], + loc: { + start: { column: 19, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/3-Babel-AST.shot new file mode 100644 index 000000000000..cd7fc6acd60d --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/3-Babel-AST.shot @@ -0,0 +1,64 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], + + range: [18, 20], + loc: { + start: { column: 18, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + + range: [14, 20], + loc: { + start: { column: 14, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "abd", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + + range: [0, 20], + loc: { + start: { column: 0, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + ], + sourceType: "script", + + range: [0, 21], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, +} +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/4-Babel-Tokens.shot new file mode 100644 index 000000000000..1779dbfd42f0 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once Babel - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "namespace", + + range: [0, 9], + loc: { + start: { column: 0, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abd", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [13, 14], + loc: { + start: { column: 13, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [18, 19], + loc: { + start: { column: 18, line: 1 }, + end: { column: 19, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [19, 20], + loc: { + start: { column: 19, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 000000000000..d07164e04ea0 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,76 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + TSModuleDeclaration { + type: 'TSModuleDeclaration', +- body: TSModuleBlock { +- type: 'TSModuleBlock', +- body: Array [], ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleBlock { ++ type: 'TSModuleBlock', ++ body: Array [], ++ ++ range: [18, 20], ++ loc: { ++ start: { column: 18, line: 1 }, ++ end: { column: 20, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'def', ++ ++ range: [14, 17], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 17, line: 1 }, ++ }, ++ }, + +- range: [18, 20], ++ range: [14, 20], + loc: { +- start: { column: 18, line: 1 }, ++ start: { column: 14, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + id: Identifier { + type: 'Identifier', +- name: 'abd.def', ++ name: 'abd', + +- range: [10, 17], ++ range: [10, 13], + loc: { + start: { column: 10, line: 1 }, +- end: { column: 17, line: 1 }, ++ end: { column: 13, line: 1 }, + }, + }, + + range: [0, 20], + loc: { + start: { column: 0, line: 1 }, + end: { column: 20, line: 1 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 21], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, + }" +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/6-AST-Alignment-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/6-AST-Alignment-Tokens.shot new file mode 100644 index 000000000000..657e47e2dc16 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/6-AST-Alignment-Tokens.shot @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/fixture.ts b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/fixture.ts new file mode 100644 index 000000000000..aa16edb5ae59 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/fixture.ts @@ -0,0 +1 @@ +namespace abc.def.ghi {} diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot new file mode 100644 index 000000000000..26c1633383cb --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot @@ -0,0 +1,45 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice TSESTree - AST 1`] = ` +Program { + type: "Program", + body: Array [ + TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], + + range: [22, 24], + loc: { + start: { column: 22, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "abc.def.ghi", + + range: [10, 21], + loc: { + start: { column: 10, line: 1 }, + end: { column: 21, line: 1 }, + }, + }, + + range: [0, 24], + loc: { + start: { column: 0, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + ], + sourceType: "script", + + range: [0, 25], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, +} +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/2-TSESTree-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/2-TSESTree-Tokens.shot new file mode 100644 index 000000000000..4f2b06d094fe --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/2-TSESTree-Tokens.shot @@ -0,0 +1,86 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice TSESTree - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "namespace", + + range: [0, 9], + loc: { + start: { column: 0, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abc", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [13, 14], + loc: { + start: { column: 13, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [17, 18], + loc: { + start: { column: 17, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "ghi", + + range: [18, 21], + loc: { + start: { column: 18, line: 1 }, + end: { column: 21, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [22, 23], + loc: { + start: { column: 22, line: 1 }, + end: { column: 23, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [23, 24], + loc: { + start: { column: 23, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/3-Babel-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/3-Babel-AST.shot new file mode 100644 index 000000000000..d694d20934af --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/3-Babel-AST.shot @@ -0,0 +1,83 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice Babel - AST 1`] = ` +Program { + type: "Program", + body: Array [ + TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleDeclaration { + type: "TSModuleDeclaration", + body: TSModuleBlock { + type: "TSModuleBlock", + body: Array [], + + range: [22, 24], + loc: { + start: { column: 22, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "ghi", + + range: [18, 21], + loc: { + start: { column: 18, line: 1 }, + end: { column: 21, line: 1 }, + }, + }, + + range: [18, 24], + loc: { + start: { column: 18, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + + range: [14, 24], + loc: { + start: { column: 14, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + id: Identifier { + type: "Identifier", + name: "abc", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + + range: [0, 24], + loc: { + start: { column: 0, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + ], + sourceType: "script", + + range: [0, 25], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, +} +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/4-Babel-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/4-Babel-Tokens.shot new file mode 100644 index 000000000000..8cf1c7e6e3bb --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/4-Babel-Tokens.shot @@ -0,0 +1,86 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice Babel - Tokens 1`] = ` +Array [ + Identifier { + type: "Identifier", + value: "namespace", + + range: [0, 9], + loc: { + start: { column: 0, line: 1 }, + end: { column: 9, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "abc", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [13, 14], + loc: { + start: { column: 13, line: 1 }, + end: { column: 14, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: ".", + + range: [17, 18], + loc: { + start: { column: 17, line: 1 }, + end: { column: 18, line: 1 }, + }, + }, + Identifier { + type: "Identifier", + value: "ghi", + + range: [18, 21], + loc: { + start: { column: 18, line: 1 }, + end: { column: 21, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "{", + + range: [22, 23], + loc: { + start: { column: 22, line: 1 }, + end: { column: 23, line: 1 }, + }, + }, + Punctuator { + type: "Punctuator", + value: "}", + + range: [23, 24], + loc: { + start: { column: 23, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, +] +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot new file mode 100644 index 000000000000..11a35dcb84b7 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice AST Alignment - AST 1`] = ` +"Snapshot Diff: +- TSESTree ++ Babel + + Program { + type: 'Program', + body: Array [ + TSModuleDeclaration { + type: 'TSModuleDeclaration', +- body: TSModuleBlock { +- type: 'TSModuleBlock', +- body: Array [], ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleDeclaration { ++ type: 'TSModuleDeclaration', ++ body: TSModuleBlock { ++ type: 'TSModuleBlock', ++ body: Array [], ++ ++ range: [22, 24], ++ loc: { ++ start: { column: 22, line: 1 }, ++ end: { column: 24, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'ghi', + +- range: [22, 24], ++ range: [18, 21], ++ loc: { ++ start: { column: 18, line: 1 }, ++ end: { column: 21, line: 1 }, ++ }, ++ }, ++ ++ range: [18, 24], ++ loc: { ++ start: { column: 18, line: 1 }, ++ end: { column: 24, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'def', ++ ++ range: [14, 17], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 17, line: 1 }, ++ }, ++ }, ++ ++ range: [14, 24], + loc: { +- start: { column: 22, line: 1 }, ++ start: { column: 14, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + id: Identifier { + type: 'Identifier', +- name: 'abc.def.ghi', ++ name: 'abc', + +- range: [10, 21], ++ range: [10, 13], + loc: { + start: { column: 10, line: 1 }, +- end: { column: 21, line: 1 }, ++ end: { column: 13, line: 1 }, + }, + }, + + range: [0, 24], + loc: { + start: { column: 0, line: 1 }, + end: { column: 24, line: 1 }, + }, + }, + ], + sourceType: 'script', + + range: [0, 25], + loc: { + start: { column: 0, line: 1 }, + end: { column: 0, line: 2 }, + }, + }" +`; diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/6-AST-Alignment-Tokens.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/6-AST-Alignment-Tokens.shot new file mode 100644 index 000000000000..f0ac1cd2c048 --- /dev/null +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/6-AST-Alignment-Tokens.shot @@ -0,0 +1,6 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice AST Alignment - Token 1`] = ` +"Snapshot Diff: +Compared values have no visual difference." +`; diff --git a/packages/ast-spec/tests/fixtures-with-differences-ast.shot b/packages/ast-spec/tests/fixtures-with-differences-ast.shot index e6ea1804e84d..999e007a2993 100644 --- a/packages/ast-spec/tests/fixtures-with-differences-ast.shot +++ b/packages/ast-spec/tests/fixtures-with-differences-ast.shot @@ -22,6 +22,10 @@ Set { "declaration/TSInterfaceDeclaration/fixtures/extends-one/fixture.ts", "declaration/TSInterfaceDeclaration/fixtures/type-param-many/fixture.ts", "declaration/TSInterfaceDeclaration/fixtures/type-param-one/fixture.ts", + "declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/fixture.ts", + "declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/fixture.ts", + "declaration/TSModuleDeclaration/fixtures/namespace-nested-once/fixture.ts", + "declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/fixture.ts", "declaration/TSTypeAliasDeclaration/fixtures/type-param-many/fixture.ts", "declaration/TSTypeAliasDeclaration/fixtures/type-param-one/fixture.ts", "element/AccessorProperty/fixtures/key-computed-complex/fixture.ts", diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 4af9163c34eb..9532b604f3de 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -254,12 +254,8 @@ export class Converter { data: Omit, 'parent'>, ): T { const result = data; - if (!result.range) { - result.range = getRange(node, this.ast); - } - if (!result.loc) { - result.loc = getLocFor(result.range[0], result.range[1], this.ast); - } + result.range ??= getRange(node, this.ast); + result.loc ??= getLocFor(result.range[0], result.range[1], this.ast); if (result && this.options.shouldPreserveNodeMaps) { this.esTreeNodeToTSNodeMap.set(result, node); @@ -735,6 +731,41 @@ export class Converter { } } + /** + * @remarks + * TypeScript produces a nested body AST for Identifier names like `abc.def`. + * This unravels their body blocks and accumulates the name if necessary. + */ + private collectModuleDeclaration( + node: ts.ModuleDeclaration, + ): [ts.Identifier | ts.ModuleBlock | undefined, TSESTree.Identifier] { + const startingNode = node; + + // String literal names (e.g. `declare module "abc"`) won't be nested. + if (ts.isStringLiteral(startingNode.name)) { + return [ + node.body as ts.ModuleBlock | undefined, + this.convertChild(node.name), + ]; + } + + let name = node.name.text; + + while (node.body && ts.isModuleDeclaration(node.body)) { + node = node.body; + name = `${name}.${node.name.text}`; + } + + return [ + node.body, + this.createNode(startingNode.name, { + name, + range: [startingNode.name.getStart(this.ast), node.name.getEnd()], + type: AST_NODE_TYPES.Identifier, + }), + ]; + } + /** * Converts a TypeScript node into an ESTree node. * The core of the conversion logic: @@ -2728,12 +2759,13 @@ export class Converter { } case SyntaxKind.ModuleDeclaration: { + const [body, id] = this.collectModuleDeclaration(node); const result = this.createNode(node, { type: AST_NODE_TYPES.TSModuleDeclaration, - id: this.convertChild(node.name), + id, }); - if (node.body) { - result.body = this.convertChild(node.body); + if (body) { + result.body = this.convertChild(body); } // apply modifiers first... if (hasModifier(SyntaxKind.DeclareKeyword, node)) { From ca97344f548e7909c89b0dc89e63a8bae28721d6 Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Mon, 6 Feb 2023 05:45:43 -0500 Subject: [PATCH 2/2] Switched to TSQualifiedName --- .../snapshots/1-TSESTree-AST.shot | 44 +++++++++- .../snapshots/5-AST-Alignment-AST.shot | 85 ++++++++++++------- .../snapshots/1-TSESTree-AST.shot | 44 +++++++++- .../snapshots/5-AST-Alignment-AST.shot | 85 ++++++++++++------- .../snapshots/1-TSESTree-AST.shot | 25 +++++- .../snapshots/5-AST-Alignment-AST.shot | 61 +++++++------ .../snapshots/1-TSESTree-AST.shot | 44 +++++++++- .../snapshots/5-AST-Alignment-AST.shot | 85 ++++++++++++------- .../declaration/TSModuleDeclaration/spec.ts | 16 +--- .../eslint-plugin/src/rules/no-namespace.ts | 2 +- packages/typescript-estree/src/convert.ts | 60 +++++++++---- .../src/ts-estree/estree-to-ts-node-types.ts | 2 +- 12 files changed, 400 insertions(+), 153 deletions(-) diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot index df20691d205f..cdba5c9b875a 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/1-TSESTree-AST.shot @@ -16,9 +16,47 @@ Program { end: { column: 15, line: 1 }, }, }, - id: Identifier { - type: "Identifier", - name: "A.B.C", + id: TSQualifiedName { + type: "TSQualifiedName", + left: TSQualifiedName { + type: "TSQualifiedName", + left: Identifier { + type: "Identifier", + name: "A", + + range: [7, 8], + loc: { + start: { column: 7, line: 1 }, + end: { column: 8, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "B", + + range: [9, 10], + loc: { + start: { column: 9, line: 1 }, + end: { column: 10, line: 1 }, + }, + }, + + range: [7, 10], + loc: { + start: { column: 7, line: 1 }, + end: { column: 10, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "C", + + range: [11, 12], + loc: { + start: { column: 11, line: 1 }, + end: { column: 12, line: 1 }, + }, + }, range: [7, 12], loc: { diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot index 344f8c6d4f16..38784db1caef 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/module-id-qualified-name/snapshots/5-AST-Alignment-AST.shot @@ -13,6 +13,20 @@ exports[`AST Fixtures declaration TSModuleDeclaration module-id-qualified-name A - body: TSModuleBlock { - type: 'TSModuleBlock', - body: Array [], +- +- range: [13, 15], +- loc: { +- start: { column: 13, line: 1 }, +- end: { column: 15, line: 1 }, +- }, +- }, +- id: TSQualifiedName { +- type: 'TSQualifiedName', +- left: TSQualifiedName { +- type: 'TSQualifiedName', +- left: Identifier { +- type: 'Identifier', +- name: 'A', + body: TSModuleDeclaration { + type: 'TSModuleDeclaration', + body: TSModuleDeclaration { @@ -20,55 +34,68 @@ exports[`AST Fixtures declaration TSModuleDeclaration module-id-qualified-name A + body: TSModuleBlock { + type: 'TSModuleBlock', + body: Array [], -+ + +- range: [7, 8], + range: [13, 15], -+ loc: { + loc: { +- start: { column: 7, line: 1 }, +- end: { column: 8, line: 1 }, + start: { column: 13, line: 1 }, + end: { column: 15, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'B', + name: 'C', -- range: [13, 15], +- range: [9, 10], + range: [11, 12], -+ loc: { + loc: { +- start: { column: 9, line: 1 }, +- end: { column: 10, line: 1 }, + start: { column: 11, line: 1 }, + end: { column: 12, line: 1 }, -+ }, -+ }, -+ + }, + }, + +- range: [7, 10], + range: [11, 15], -+ loc: { + loc: { +- start: { column: 7, line: 1 }, +- end: { column: 10, line: 1 }, + start: { column: 11, line: 1 }, + end: { column: 15, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'C', + name: 'B', -+ + +- range: [11, 12], + range: [9, 10], -+ loc: { + loc: { +- start: { column: 11, line: 1 }, +- end: { column: 12, line: 1 }, + start: { column: 9, line: 1 }, + end: { column: 10, line: 1 }, -+ }, -+ }, -+ -+ range: [9, 15], - loc: { -- start: { column: 13, line: 1 }, -+ start: { column: 9, line: 1 }, - end: { column: 15, line: 1 }, + }, }, - }, - id: Identifier { - type: 'Identifier', -- name: 'A.B.C', -+ name: 'A', - range: [7, 12], ++ range: [9, 15], ++ loc: { ++ start: { column: 9, line: 1 }, ++ end: { column: 15, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'A', ++ + range: [7, 8], loc: { start: { column: 7, line: 1 }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot index 03da1caa8b3c..83a1ab2fee75 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/1-TSESTree-AST.shot @@ -16,9 +16,47 @@ Program { end: { column: 18, line: 1 }, }, }, - id: Identifier { - type: "Identifier", - name: "A.B.C", + id: TSQualifiedName { + type: "TSQualifiedName", + left: TSQualifiedName { + type: "TSQualifiedName", + left: Identifier { + type: "Identifier", + name: "A", + + range: [10, 11], + loc: { + start: { column: 10, line: 1 }, + end: { column: 11, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "B", + + range: [12, 13], + loc: { + start: { column: 12, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "C", + + range: [14, 15], + loc: { + start: { column: 14, line: 1 }, + end: { column: 15, line: 1 }, + }, + }, range: [10, 15], loc: { diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot index cc5a251b954d..be0efaa908b5 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-id-qualified-name/snapshots/5-AST-Alignment-AST.shot @@ -13,6 +13,20 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-id-qualified-nam - body: TSModuleBlock { - type: 'TSModuleBlock', - body: Array [], +- +- range: [16, 18], +- loc: { +- start: { column: 16, line: 1 }, +- end: { column: 18, line: 1 }, +- }, +- }, +- id: TSQualifiedName { +- type: 'TSQualifiedName', +- left: TSQualifiedName { +- type: 'TSQualifiedName', +- left: Identifier { +- type: 'Identifier', +- name: 'A', + body: TSModuleDeclaration { + type: 'TSModuleDeclaration', + body: TSModuleDeclaration { @@ -20,55 +34,68 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-id-qualified-nam + body: TSModuleBlock { + type: 'TSModuleBlock', + body: Array [], -+ + +- range: [10, 11], + range: [16, 18], -+ loc: { + loc: { +- start: { column: 10, line: 1 }, +- end: { column: 11, line: 1 }, + start: { column: 16, line: 1 }, + end: { column: 18, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'B', + name: 'C', -- range: [16, 18], +- range: [12, 13], + range: [14, 15], -+ loc: { + loc: { +- start: { column: 12, line: 1 }, +- end: { column: 13, line: 1 }, + start: { column: 14, line: 1 }, + end: { column: 15, line: 1 }, -+ }, -+ }, -+ + }, + }, + +- range: [10, 13], + range: [14, 18], -+ loc: { + loc: { +- start: { column: 10, line: 1 }, +- end: { column: 13, line: 1 }, + start: { column: 14, line: 1 }, + end: { column: 18, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'C', + name: 'B', -+ + +- range: [14, 15], + range: [12, 13], -+ loc: { + loc: { +- start: { column: 14, line: 1 }, +- end: { column: 15, line: 1 }, + start: { column: 12, line: 1 }, + end: { column: 13, line: 1 }, -+ }, -+ }, -+ -+ range: [12, 18], - loc: { -- start: { column: 16, line: 1 }, -+ start: { column: 12, line: 1 }, - end: { column: 18, line: 1 }, + }, }, - }, - id: Identifier { - type: 'Identifier', -- name: 'A.B.C', -+ name: 'A', - range: [10, 15], ++ range: [12, 18], ++ loc: { ++ start: { column: 12, line: 1 }, ++ end: { column: 18, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'A', ++ + range: [10, 11], loc: { start: { column: 10, line: 1 }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot index e4cd973cb92d..faaa366b2469 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/1-TSESTree-AST.shot @@ -16,9 +16,28 @@ Program { end: { column: 20, line: 1 }, }, }, - id: Identifier { - type: "Identifier", - name: "abd.def", + id: TSQualifiedName { + type: "TSQualifiedName", + left: Identifier { + type: "Identifier", + name: "abd", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, range: [10, 17], loc: { diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot index d07164e04ea0..a41a0c8b73c8 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-once/snapshots/5-AST-Alignment-AST.shot @@ -13,43 +13,56 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-once AST - body: TSModuleBlock { - type: 'TSModuleBlock', - body: Array [], +- +- range: [18, 20], +- loc: { +- start: { column: 18, line: 1 }, +- end: { column: 20, line: 1 }, +- }, +- }, +- id: TSQualifiedName { +- type: 'TSQualifiedName', +- left: Identifier { +- type: 'Identifier', +- name: 'abd', + body: TSModuleDeclaration { + type: 'TSModuleDeclaration', + body: TSModuleBlock { + type: 'TSModuleBlock', + body: Array [], -+ + +- range: [10, 13], + range: [18, 20], -+ loc: { + loc: { +- start: { column: 10, line: 1 }, +- end: { column: 13, line: 1 }, + start: { column: 18, line: 1 }, + end: { column: 20, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', -+ name: 'def', -+ -+ range: [14, 17], -+ loc: { -+ start: { column: 14, line: 1 }, -+ end: { column: 17, line: 1 }, -+ }, -+ }, + type: 'Identifier', + name: 'def', -- range: [18, 20], -+ range: [14, 20], - loc: { -- start: { column: 18, line: 1 }, -+ start: { column: 14, line: 1 }, - end: { column: 20, line: 1 }, + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, }, - }, - id: Identifier { - type: 'Identifier', -- name: 'abd.def', -+ name: 'abd', - range: [10, 17], ++ range: [14, 20], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 20, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'abd', ++ + range: [10, 13], loc: { start: { column: 10, line: 1 }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot index 26c1633383cb..796d2b1fb4a4 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/1-TSESTree-AST.shot @@ -16,9 +16,47 @@ Program { end: { column: 24, line: 1 }, }, }, - id: Identifier { - type: "Identifier", - name: "abc.def.ghi", + id: TSQualifiedName { + type: "TSQualifiedName", + left: TSQualifiedName { + type: "TSQualifiedName", + left: Identifier { + type: "Identifier", + name: "abc", + + range: [10, 13], + loc: { + start: { column: 10, line: 1 }, + end: { column: 13, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "def", + + range: [14, 17], + loc: { + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + + range: [10, 17], + loc: { + start: { column: 10, line: 1 }, + end: { column: 17, line: 1 }, + }, + }, + right: Identifier { + type: "Identifier", + name: "ghi", + + range: [18, 21], + loc: { + start: { column: 18, line: 1 }, + end: { column: 21, line: 1 }, + }, + }, range: [10, 21], loc: { diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot index 11a35dcb84b7..8f8420a7c706 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/fixtures/namespace-nested-twice/snapshots/5-AST-Alignment-AST.shot @@ -13,6 +13,20 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice AST - body: TSModuleBlock { - type: 'TSModuleBlock', - body: Array [], +- +- range: [22, 24], +- loc: { +- start: { column: 22, line: 1 }, +- end: { column: 24, line: 1 }, +- }, +- }, +- id: TSQualifiedName { +- type: 'TSQualifiedName', +- left: TSQualifiedName { +- type: 'TSQualifiedName', +- left: Identifier { +- type: 'Identifier', +- name: 'abc', + body: TSModuleDeclaration { + type: 'TSModuleDeclaration', + body: TSModuleDeclaration { @@ -20,55 +34,68 @@ exports[`AST Fixtures declaration TSModuleDeclaration namespace-nested-twice AST + body: TSModuleBlock { + type: 'TSModuleBlock', + body: Array [], -+ + +- range: [10, 13], + range: [22, 24], -+ loc: { + loc: { +- start: { column: 10, line: 1 }, +- end: { column: 13, line: 1 }, + start: { column: 22, line: 1 }, + end: { column: 24, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'def', + name: 'ghi', -- range: [22, 24], +- range: [14, 17], + range: [18, 21], -+ loc: { + loc: { +- start: { column: 14, line: 1 }, +- end: { column: 17, line: 1 }, + start: { column: 18, line: 1 }, + end: { column: 21, line: 1 }, -+ }, -+ }, -+ + }, + }, + +- range: [10, 17], + range: [18, 24], -+ loc: { + loc: { +- start: { column: 10, line: 1 }, +- end: { column: 17, line: 1 }, + start: { column: 18, line: 1 }, + end: { column: 24, line: 1 }, -+ }, -+ }, + }, + }, +- right: Identifier { + id: Identifier { -+ type: 'Identifier', + type: 'Identifier', +- name: 'ghi', + name: 'def', -+ + +- range: [18, 21], + range: [14, 17], -+ loc: { + loc: { +- start: { column: 18, line: 1 }, +- end: { column: 21, line: 1 }, + start: { column: 14, line: 1 }, + end: { column: 17, line: 1 }, -+ }, -+ }, -+ -+ range: [14, 24], - loc: { -- start: { column: 22, line: 1 }, -+ start: { column: 14, line: 1 }, - end: { column: 24, line: 1 }, + }, }, - }, - id: Identifier { - type: 'Identifier', -- name: 'abc.def.ghi', -+ name: 'abc', - range: [10, 21], ++ range: [14, 24], ++ loc: { ++ start: { column: 14, line: 1 }, ++ end: { column: 24, line: 1 }, ++ }, ++ }, ++ id: Identifier { ++ type: 'Identifier', ++ name: 'abc', ++ + range: [10, 13], loc: { start: { column: 10, line: 1 }, diff --git a/packages/ast-spec/src/declaration/TSModuleDeclaration/spec.ts b/packages/ast-spec/src/declaration/TSModuleDeclaration/spec.ts index 79166ff38f9e..a61d3fa43519 100644 --- a/packages/ast-spec/src/declaration/TSModuleDeclaration/spec.ts +++ b/packages/ast-spec/src/declaration/TSModuleDeclaration/spec.ts @@ -2,6 +2,7 @@ import type { AST_NODE_TYPES } from '../../ast-node-types'; import type { BaseNode } from '../../base/BaseNode'; import type { Identifier } from '../../expression/Identifier/spec'; import type { TSModuleBlock } from '../../special/TSModuleBlock/spec'; +import type { TSQualifiedName } from '../../type/spec'; import type { Literal } from '../../unions/Literal'; export interface TSModuleDeclaration extends BaseNode { @@ -14,24 +15,13 @@ export interface TSModuleDeclaration extends BaseNode { * module 'a' {} * ``` */ - id: Identifier | Literal; + id: Identifier | Literal | TSQualifiedName; /** * The body of the module. * This can only be `undefined` for the code `declare module 'mod';` * This will be a `TSModuleDeclaration` if the name is "nested" (`Foo.Bar`). */ - body?: - | TSModuleBlock - /* - TODO(#4966) - we currently emit this due to bad parser handling of nested modules - namespace Foo.Bar {} - ^^^^^^^^^^^^^^^^^^^^ TSModuleDeclaration - ^^^^^^ TSModuleDeclaration - ^^ TSModuleBlock - - This should instead emit a TSQualifiedName for the `id` and not emit an inner TSModuleDeclaration - */ - | TSModuleDeclaration; + body?: TSModuleBlock; /** * Whether this is a global declaration * ``` diff --git a/packages/eslint-plugin/src/rules/no-namespace.ts b/packages/eslint-plugin/src/rules/no-namespace.ts index 40920077ab44..fa0e1f9bcdbe 100644 --- a/packages/eslint-plugin/src/rules/no-namespace.ts +++ b/packages/eslint-plugin/src/rules/no-namespace.ts @@ -63,7 +63,7 @@ export default util.createRule({ } return { - "TSModuleDeclaration[global!=true][id.type='Identifier']"( + "TSModuleDeclaration[global!=true][id.type!='Literal']"( node: TSESTree.TSModuleDeclaration, ): void { if ( diff --git a/packages/typescript-estree/src/convert.ts b/packages/typescript-estree/src/convert.ts index 9532b604f3de..6692a63e90f4 100644 --- a/packages/typescript-estree/src/convert.ts +++ b/packages/typescript-estree/src/convert.ts @@ -738,32 +738,62 @@ export class Converter { */ private collectModuleDeclaration( node: ts.ModuleDeclaration, - ): [ts.Identifier | ts.ModuleBlock | undefined, TSESTree.Identifier] { - const startingNode = node; - + ): [ + ts.Identifier | ts.ModuleBlock | undefined, + TSESTree.Identifier | TSESTree.TSQualifiedName, + ] { // String literal names (e.g. `declare module "abc"`) won't be nested. - if (ts.isStringLiteral(startingNode.name)) { + if (ts.isStringLiteral(node.name)) { return [ node.body as ts.ModuleBlock | undefined, this.convertChild(node.name), ]; } - let name = node.name.text; + // If the node has no no body or isn't a module declaration, it's not nested. + // We can assume its name is a single identifier. + if (!node.body || !ts.isModuleDeclaration(node.body)) { + return [ + node.body, + this.createNode(node.name, { + name: node.name.text, + range: [node.name.getStart(this.ast), node.name.getEnd()], + type: AST_NODE_TYPES.Identifier, + }), + ]; + } + + // Nested module declarations are stored in TypeScript as nested tree nodes. + // We "unravel" them here by making our own nested TSQualifiedName, + // with the innermost node's body as the actual node body. + + let name: TSESTree.Identifier | TSESTree.TSQualifiedName = + this.createNode(node.name, { + name: node.name.text, + range: [node.name.getStart(this.ast), node.name.getEnd()], + type: AST_NODE_TYPES.Identifier, + }); - while (node.body && ts.isModuleDeclaration(node.body)) { + do { node = node.body; - name = `${name}.${node.name.text}`; - } - return [ - node.body, - this.createNode(startingNode.name, { - name, - range: [startingNode.name.getStart(this.ast), node.name.getEnd()], + const nextName = node.name as ts.Identifier; + + const right = this.createNode(nextName, { + name: nextName.text, + range: [nextName.getStart(this.ast), nextName.getEnd()], type: AST_NODE_TYPES.Identifier, - }), - ]; + }); + + name = this.createNode(nextName, { + left: name, + right: right, + range: [name.range[0], right.range[1]], + type: AST_NODE_TYPES.TSQualifiedName, + }); + } while (node.body && ts.isModuleDeclaration(node.body)); + + return [node.body, name]; } /** diff --git a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts index 9c99786dfca3..887bda8696f2 100644 --- a/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts +++ b/packages/typescript-estree/src/ts-estree/estree-to-ts-node-types.ts @@ -202,7 +202,7 @@ export interface EstreeToTsNodeTypes { [AST_NODE_TYPES.TSOptionalType]: ts.OptionalTypeNode; [AST_NODE_TYPES.TSParameterProperty]: ts.ParameterDeclaration; [AST_NODE_TYPES.TSPropertySignature]: ts.PropertySignature; - [AST_NODE_TYPES.TSQualifiedName]: ts.QualifiedName; + [AST_NODE_TYPES.TSQualifiedName]: ts.Identifier | ts.QualifiedName; [AST_NODE_TYPES.TSRestType]: | ts.RestTypeNode // for consistency and following babel's choices, a named tuple member with a rest gets converted to a TSRestType