@@ -123,43 +123,54 @@ void addFunctionSymbol(FunctionDef functionDef, @Nullable String fullyQualifiedN
123123 }
124124
125125 private Symbol copySymbol (String symbolName , Symbol symbol ) {
126- if (symbol .is (Symbol .Kind .FUNCTION )) {
127- return new FunctionSymbolImpl (symbolName , (FunctionSymbol ) symbol );
128- } else if (symbol .is (Symbol .Kind .CLASS )) {
129- ClassSymbolImpl originalClassSymbol = (ClassSymbolImpl ) symbol ;
130- // Must use symbolName to preserve import aliases
131- ClassSymbolImpl classSymbol =
132- new ClassSymbolImpl (symbolName , originalClassSymbol .fullyQualifiedName (),
133- originalClassSymbol .definitionLocation (), originalClassSymbol .hasDecorators (), originalClassSymbol .hasMetaClass (), originalClassSymbol .metaclassFQN ());
134- for (Symbol originalSymbol : originalClassSymbol .superClasses ()) {
135- Symbol globalSymbol = projectLevelSymbolTable .getSymbol (originalSymbol .fullyQualifiedName ());
136- if (globalSymbol != null && globalSymbol .kind () == Symbol .Kind .CLASS ) {
137- classSymbol .addSuperClass (copySymbol (globalSymbol .name (), globalSymbol ));
138- } else {
139- classSymbol .addSuperClass (originalSymbol );
126+ return copySymbol (symbolName , symbol , new HashSet <>());
127+ }
128+
129+ private Symbol copySymbol (String symbolName , Symbol symbol , Set <Symbol > alreadyVisitedSymbols ) {
130+ alreadyVisitedSymbols .add (symbol );
131+ switch (symbol .kind ()) {
132+ case FUNCTION :
133+ return new FunctionSymbolImpl (symbolName , (FunctionSymbol ) symbol );
134+ case CLASS :
135+ return copyClassSymbol (symbolName , (ClassSymbolImpl ) symbol , alreadyVisitedSymbols );
136+ case AMBIGUOUS :
137+ Set <Symbol > alternativeSymbols = ((AmbiguousSymbol ) symbol ).alternatives ().stream ()
138+ .map (s -> copySymbol (symbolName , s , alreadyVisitedSymbols ))
139+ .collect (Collectors .toSet ());
140+ return new AmbiguousSymbolImpl (symbolName , symbol .fullyQualifiedName (), alternativeSymbols );
141+ default :
142+ SymbolImpl copiedSymbol = new SymbolImpl (symbolName , symbol .fullyQualifiedName (), symbol .annotatedTypeName ());
143+ for (Map .Entry <String , Symbol > kv : ((SymbolImpl ) symbol ).getChildrenSymbolByName ().entrySet ()) {
144+ copiedSymbol .addChildSymbol (((SymbolImpl ) kv .getValue ()).copyWithoutUsages ());
140145 }
146+ return copiedSymbol ;
147+ }
148+ }
149+
150+ private ClassSymbolImpl copyClassSymbol (String symbolName , ClassSymbolImpl originalClassSymbol , Set <Symbol > alreadyVisitedSymbols ) {
151+ // Must use symbolName to preserve import aliases
152+ ClassSymbolImpl classSymbol = new ClassSymbolImpl (symbolName , originalClassSymbol .fullyQualifiedName (), originalClassSymbol .definitionLocation (),
153+ originalClassSymbol .hasDecorators (), originalClassSymbol .hasMetaClass (), originalClassSymbol .metaclassFQN ());
154+
155+ for (Symbol originalSymbol : originalClassSymbol .superClasses ()) {
156+ Symbol globalSymbol = projectLevelSymbolTable .getSymbol (originalSymbol .fullyQualifiedName ());
157+ if (globalSymbol != null && globalSymbol .kind () == Symbol .Kind .CLASS ) {
158+ Symbol parentClass = alreadyVisitedSymbols .contains (globalSymbol )
159+ ? new SymbolImpl (globalSymbol .name (), globalSymbol .fullyQualifiedName ())
160+ : copySymbol (globalSymbol .name (), globalSymbol , alreadyVisitedSymbols );
161+ classSymbol .addSuperClass (parentClass );
162+ } else {
163+ classSymbol .addSuperClass (originalSymbol );
141164 }
142- classSymbol .addMembers (originalClassSymbol
143- .declaredMembers ().stream ()
144- .map (m -> ((SymbolImpl ) m ).copyWithoutUsages ())
145- .collect (Collectors .toList ()));
146- if (originalClassSymbol .hasSuperClassWithoutSymbol ()) {
147- classSymbol .setHasSuperClassWithoutSymbol ();
148- }
149- return classSymbol ;
150- } else if (symbol .is (Symbol .Kind .AMBIGUOUS )) {
151- Set <Symbol > alternativeSymbols = ((AmbiguousSymbol ) symbol ).alternatives ().stream ()
152- .map (s -> copySymbol (symbolName , s ))
153- .collect (Collectors .toSet ());
154- return new AmbiguousSymbolImpl (symbolName , symbol .fullyQualifiedName (), alternativeSymbols );
155- } else if (symbol .is (Symbol .Kind .OTHER )) {
156- SymbolImpl res = new SymbolImpl (symbolName , symbol .fullyQualifiedName (), symbol .annotatedTypeName ());
157- for (Map .Entry <String , Symbol > kv : ((SymbolImpl ) symbol ).getChildrenSymbolByName ().entrySet ()) {
158- res .addChildSymbol (((SymbolImpl ) kv .getValue ()).copyWithoutUsages ());
159- }
160- return res ;
161165 }
162- return new SymbolImpl (symbolName , symbol .fullyQualifiedName ());
166+ classSymbol .addMembers (originalClassSymbol
167+ .declaredMembers ().stream ()
168+ .map (m -> ((SymbolImpl ) m ).copyWithoutUsages ())
169+ .collect (Collectors .toList ()));
170+ if (originalClassSymbol .hasSuperClassWithoutSymbol ()) {
171+ classSymbol .setHasSuperClassWithoutSymbol ();
172+ }
173+ return classSymbol ;
163174 }
164175
165176 void addModuleSymbol (Name nameTree , @ CheckForNull String fullyQualifiedName ) {
0 commit comments