Skip to content

Commit 7ee8b4e

Browse files
authored
Consistently error on full circle of circular import aliases (#1904)
1 parent 30cbd10 commit 7ee8b4e

15 files changed

+170
-28
lines changed

internal/ast/symbol.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ const (
4343
InternalSymbolNameClass = InternalSymbolNamePrefix + "class" // Unnamed class expression
4444
InternalSymbolNameFunction = InternalSymbolNamePrefix + "function" // Unnamed function expression
4545
InternalSymbolNameComputed = InternalSymbolNamePrefix + "computed" // Computed property name declaration with dynamic name
46-
InternalSymbolNameResolving = InternalSymbolNamePrefix + "resolving" // Indicator symbol used to mark partially resolved type aliases
4746
InternalSymbolNameInstantiationExpression = InternalSymbolNamePrefix + "instantiationExpression" // Instantiation expressions
4847
InternalSymbolNameImportAttributes = InternalSymbolNamePrefix + "importAttributes"
4948
InternalSymbolNameExportEquals = "export=" // Export assignment symbol

internal/checker/checker.go

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const (
6161
TypeSystemPropertyNameResolvedBaseTypes
6262
TypeSystemPropertyNameWriteType
6363
TypeSystemPropertyNameInitializerIsUndefined
64+
TypeSystemPropertyNameAliasTarget
6465
)
6566

6667
type TypeResolution struct {
@@ -618,7 +619,6 @@ type Checker struct {
618619
argumentsSymbol *ast.Symbol
619620
requireSymbol *ast.Symbol
620621
unknownSymbol *ast.Symbol
621-
resolvingSymbol *ast.Symbol
622622
unresolvedSymbols map[string]*ast.Symbol
623623
errorTypes map[string]*Type
624624
globalThisSymbol *ast.Symbol
@@ -915,7 +915,6 @@ func NewChecker(program Program) *Checker {
915915
c.argumentsSymbol = c.newSymbol(ast.SymbolFlagsProperty, "arguments")
916916
c.requireSymbol = c.newSymbol(ast.SymbolFlagsProperty, "require")
917917
c.unknownSymbol = c.newSymbol(ast.SymbolFlagsProperty, "unknown")
918-
c.resolvingSymbol = c.newSymbol(ast.SymbolFlagsNone, ast.InternalSymbolNameResolving)
919918
c.unresolvedSymbols = make(map[string]*ast.Symbol)
920919
c.errorTypes = make(map[string]*Type)
921920
c.globalThisSymbol = c.newSymbolEx(ast.SymbolFlagsModule, "globalThis", ast.CheckFlagsReadonly)
@@ -15652,29 +15651,25 @@ func (c *Checker) resolveAlias(symbol *ast.Symbol) *ast.Symbol {
1565215651
}
1565315652
links := c.aliasSymbolLinks.Get(symbol)
1565415653
if links.aliasTarget == nil {
15655-
links.aliasTarget = c.resolvingSymbol
15654+
if !c.pushTypeResolution(symbol, TypeSystemPropertyNameAliasTarget) {
15655+
return c.unknownSymbol
15656+
}
1565615657
node := c.getDeclarationOfAliasSymbol(symbol)
1565715658
if node == nil {
1565815659
panic("Unexpected nil in resolveAlias for symbol: " + c.symbolToString(symbol))
1565915660
}
15660-
target := c.getTargetOfAliasDeclaration(node, false /*dontRecursivelyResolve*/)
15661-
if links.aliasTarget == c.resolvingSymbol {
15662-
if target == nil {
15663-
target = c.unknownSymbol
15664-
}
15665-
links.aliasTarget = target
15666-
} else {
15661+
links.aliasTarget = core.OrElse(c.getTargetOfAliasDeclaration(node, false /*dontRecursivelyResolve*/), c.unknownSymbol)
15662+
if !c.popTypeResolution() {
1566715663
c.error(node, diagnostics.Circular_definition_of_import_alias_0, c.symbolToString(symbol))
15664+
links.aliasTarget = c.unknownSymbol
1566815665
}
15669-
} else if links.aliasTarget == c.resolvingSymbol {
15670-
links.aliasTarget = c.unknownSymbol
1567115666
}
1567215667
return links.aliasTarget
1567315668
}
1567415669

1567515670
func (c *Checker) tryResolveAlias(symbol *ast.Symbol) *ast.Symbol {
1567615671
links := c.aliasSymbolLinks.Get(symbol)
15677-
if links.aliasTarget != c.resolvingSymbol {
15672+
if links.aliasTarget != nil || c.findResolutionCycleStartIndex(symbol, TypeSystemPropertyNameAliasTarget) < 0 {
1567815673
return c.resolveAlias(symbol)
1567915674
}
1568015675
return nil
@@ -18097,6 +18092,8 @@ func (c *Checker) typeResolutionHasProperty(r *TypeResolution) bool {
1809718092
return c.nodeLinks.Get(r.target.(*ast.Node)).flags&NodeCheckFlagsInitializerIsUndefinedComputed != 0
1809818093
case TypeSystemPropertyNameWriteType:
1809918094
return c.valueSymbolLinks.Get(r.target.(*ast.Symbol)).writeType != nil
18095+
case TypeSystemPropertyNameAliasTarget:
18096+
return c.aliasSymbolLinks.Get(r.target.(*ast.Symbol)).aliasTarget != nil
1810018097
}
1810118098
panic("Unhandled case in typeResolutionHasProperty")
1810218099
}

internal/testrunner/compiler_runner.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,11 +337,6 @@ func newCompilerTest(
337337
}
338338

339339
var concurrentSkippedErrorBaselines = map[string]string{
340-
"circular1.ts": "Circular error reported in an extra position.",
341-
"circular3.ts": "Circular error reported in an extra position.",
342-
"recursiveExportAssignmentAndFindAliasedType1.ts": "Circular error reported in an extra position.",
343-
"recursiveExportAssignmentAndFindAliasedType2.ts": "Circular error reported in an extra position.",
344-
"recursiveExportAssignmentAndFindAliasedType3.ts": "Circular error reported in an extra position.",
345340
"typeOnlyMerge2.ts": "Type-only merging is not detected when files are checked on different checkers.",
346341
"typeOnlyMerge3.ts": "Type-only merging is not detected when files are checked on different checkers.",
347342
}

testdata/baselines/reference/submodule/compiler/circularModuleImports.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
circularModuleImports.ts(5,5): error TS2303: Circular definition of import alias 'A'.
2+
circularModuleImports.ts(7,5): error TS2303: Circular definition of import alias 'B'.
23

34

4-
==== circularModuleImports.ts (1 errors) ====
5+
==== circularModuleImports.ts (2 errors) ====
56
module M
67

78
{
@@ -11,6 +12,8 @@ circularModuleImports.ts(5,5): error TS2303: Circular definition of import alias
1112
!!! error TS2303: Circular definition of import alias 'A'.
1213

1314
import B = A;
15+
~~~~~~~~~~~~~
16+
!!! error TS2303: Circular definition of import alias 'B'.
1417

1518
}
1619

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--- old.circularModuleImports.errors.txt
2+
+++ new.circularModuleImports.errors.txt
3+
@@= skipped -0, +0 lines =@@
4+
circularModuleImports.ts(5,5): error TS2303: Circular definition of import alias 'A'.
5+
-
6+
-
7+
-==== circularModuleImports.ts (1 errors) ====
8+
+circularModuleImports.ts(7,5): error TS2303: Circular definition of import alias 'B'.
9+
+
10+
+
11+
+==== circularModuleImports.ts (2 errors) ====
12+
module M
13+
14+
{
15+
@@= skipped -10, +11 lines =@@
16+
!!! error TS2303: Circular definition of import alias 'A'.
17+
18+
import B = A;
19+
+ ~~~~~~~~~~~~~
20+
+!!! error TS2303: Circular definition of import alias 'B'.
21+
22+
}
23+
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
declarationEmitUnknownImport.ts(1,1): error TS2303: Circular definition of import alias 'Foo'.
22
declarationEmitUnknownImport.ts(1,14): error TS2304: Cannot find name 'SomeNonExistingName'.
33
declarationEmitUnknownImport.ts(1,14): error TS2503: Cannot find namespace 'SomeNonExistingName'.
4+
declarationEmitUnknownImport.ts(2,9): error TS2303: Circular definition of import alias 'Foo'.
45

56

6-
==== declarationEmitUnknownImport.ts (3 errors) ====
7+
==== declarationEmitUnknownImport.ts (4 errors) ====
78
import Foo = SomeNonExistingName
89
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
910
!!! error TS2303: Circular definition of import alias 'Foo'.
1011
~~~~~~~~~~~~~~~~~~~
1112
!!! error TS2304: Cannot find name 'SomeNonExistingName'.
1213
~~~~~~~~~~~~~~~~~~~
1314
!!! error TS2503: Cannot find namespace 'SomeNonExistingName'.
14-
export {Foo}
15+
export {Foo}
16+
~~~
17+
!!! error TS2303: Circular definition of import alias 'Foo'.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--- old.declarationEmitUnknownImport.errors.txt
2+
+++ new.declarationEmitUnknownImport.errors.txt
3+
@@= skipped -0, +0 lines =@@
4+
declarationEmitUnknownImport.ts(1,1): error TS2303: Circular definition of import alias 'Foo'.
5+
declarationEmitUnknownImport.ts(1,14): error TS2304: Cannot find name 'SomeNonExistingName'.
6+
declarationEmitUnknownImport.ts(1,14): error TS2503: Cannot find namespace 'SomeNonExistingName'.
7+
-
8+
-
9+
-==== declarationEmitUnknownImport.ts (3 errors) ====
10+
+declarationEmitUnknownImport.ts(2,9): error TS2303: Circular definition of import alias 'Foo'.
11+
+
12+
+
13+
+==== declarationEmitUnknownImport.ts (4 errors) ====
14+
import Foo = SomeNonExistingName
15+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16+
!!! error TS2303: Circular definition of import alias 'Foo'.
17+
@@= skipped -11, +12 lines =@@
18+
~~~~~~~~~~~~~~~~~~~
19+
!!! error TS2503: Cannot find namespace 'SomeNonExistingName'.
20+
export {Foo}
21+
+ ~~~
22+
+!!! error TS2303: Circular definition of import alias 'Foo'.

testdata/baselines/reference/submodule/compiler/declarationEmitUnknownImport2.errors.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ declarationEmitUnknownImport2.ts(1,12): error TS1005: '=' expected.
33
declarationEmitUnknownImport2.ts(1,12): error TS2304: Cannot find name 'From'.
44
declarationEmitUnknownImport2.ts(1,12): error TS2503: Cannot find namespace 'From'.
55
declarationEmitUnknownImport2.ts(1,17): error TS1005: ';' expected.
6+
declarationEmitUnknownImport2.ts(2,1): error TS2303: Circular definition of import alias 'Foo'.
67

78

8-
==== declarationEmitUnknownImport2.ts (5 errors) ====
9+
==== declarationEmitUnknownImport2.ts (6 errors) ====
910
import Foo From './Foo'; // Syntax error
1011
~~~~~~~~~~~~~~~
1112
!!! error TS2303: Circular definition of import alias 'Foo'.
@@ -17,4 +18,6 @@ declarationEmitUnknownImport2.ts(1,17): error TS1005: ';' expected.
1718
!!! error TS2503: Cannot find namespace 'From'.
1819
~~~~~~~
1920
!!! error TS1005: ';' expected.
20-
export default Foo
21+
export default Foo
22+
~~~~~~~~~~~~~~~~~~
23+
!!! error TS2303: Circular definition of import alias 'Foo'.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--- old.declarationEmitUnknownImport2.errors.txt
2+
+++ new.declarationEmitUnknownImport2.errors.txt
3+
@@= skipped -2, +2 lines =@@
4+
declarationEmitUnknownImport2.ts(1,12): error TS2304: Cannot find name 'From'.
5+
declarationEmitUnknownImport2.ts(1,12): error TS2503: Cannot find namespace 'From'.
6+
declarationEmitUnknownImport2.ts(1,17): error TS1005: ';' expected.
7+
-
8+
-
9+
-==== declarationEmitUnknownImport2.ts (5 errors) ====
10+
+declarationEmitUnknownImport2.ts(2,1): error TS2303: Circular definition of import alias 'Foo'.
11+
+
12+
+
13+
+==== declarationEmitUnknownImport2.ts (6 errors) ====
14+
import Foo From './Foo'; // Syntax error
15+
~~~~~~~~~~~~~~~
16+
!!! error TS2303: Circular definition of import alias 'Foo'.
17+
@@= skipped -15, +16 lines =@@
18+
~~~~~~~
19+
!!! error TS1005: ';' expected.
20+
export default Foo
21+
+ ~~~~~~~~~~~~~~~~~~
22+
+!!! error TS2303: Circular definition of import alias 'Foo'.

testdata/baselines/reference/submodule/compiler/exportAsNamespaceConflict.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
/a.d.ts(2,1): error TS2303: Circular definition of import alias 'N'.
12
/a.d.ts(3,1): error TS2303: Circular definition of import alias 'N'.
23

34

4-
==== /a.d.ts (1 errors) ====
5+
==== /a.d.ts (2 errors) ====
56
declare global { namespace N {} }
67
export = N;
8+
~~~~~~~~~~~
9+
!!! error TS2303: Circular definition of import alias 'N'.
710
export as namespace N;
811
~~~~~~~~~~~~~~~~~~~~~~
912
!!! error TS2303: Circular definition of import alias 'N'.

0 commit comments

Comments
 (0)