Skip to content

Commit 6ae387a

Browse files
fix: resolution of references to declarations of wrong node type (#599)
### Summary of Changes References to declarations of the wrong node type were incorrectly resolved if they were imported in a qualified import. This PR adds tests to reproduce the bug and the missing check of the node type. --------- Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
1 parent 4c61b8c commit 6ae387a

File tree

7 files changed

+44
-23
lines changed

7 files changed

+44
-23
lines changed

src/language/scoping/safe-ds-scope-provider.ts

+21-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
AstNode,
33
AstNodeDescription,
4+
AstReflection,
45
DefaultScopeProvider,
56
EMPTY_SCOPE,
67
getContainerOfType,
@@ -62,12 +63,14 @@ import { SafeDsTypeComputer } from '../typing/safe-ds-type-computer.js';
6263
import { SafeDsPackageManager } from '../workspace/safe-ds-package-manager.js';
6364

6465
export class SafeDsScopeProvider extends DefaultScopeProvider {
66+
private readonly astReflection: AstReflection;
6567
private readonly packageManager: SafeDsPackageManager;
6668
private readonly typeComputer: SafeDsTypeComputer;
6769

6870
constructor(services: SafeDsServices) {
6971
super(services);
7072

73+
this.astReflection = services.shared.AstReflection;
7174
this.packageManager = services.workspace.PackageManager;
7275
this.typeComputer = services.types.TypeComputer;
7376
}
@@ -350,6 +353,23 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
350353
return this.createScope(explicitlyImportedDeclarations, outerScope);
351354
}
352355

356+
private builtinDeclarations(referenceType: string): AstNodeDescription[] {
357+
return this.packageManager.getDeclarationsInPackageOrSubpackage('safeds', {
358+
nodeType: referenceType,
359+
hideInternal: true,
360+
});
361+
}
362+
363+
private declarationsInSamePackage(packageName: string | null, referenceType: string): AstNodeDescription[] {
364+
if (!packageName) {
365+
return [];
366+
}
367+
368+
return this.packageManager.getDeclarationsInPackage(packageName, {
369+
nodeType: referenceType,
370+
});
371+
}
372+
353373
private explicitlyImportedDeclarations(referenceType: string, node: AstNode): AstNodeDescription[] {
354374
const containingModule = getContainerOfType(node, isSdsModule);
355375
const imports = importsOrEmpty(containingModule);
@@ -359,7 +379,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
359379
if (isSdsQualifiedImport(imp)) {
360380
for (const importedDeclaration of importedDeclarationsOrEmpty(imp)) {
361381
const description = importedDeclaration.declaration.$nodeDescription;
362-
if (!description) {
382+
if (!description || !this.astReflection.isSubtype(description.type, referenceType)) {
363383
continue;
364384
}
365385

@@ -380,21 +400,4 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
380400

381401
return result;
382402
}
383-
384-
private declarationsInSamePackage(packageName: string | null, referenceType: string): AstNodeDescription[] {
385-
if (!packageName) {
386-
return [];
387-
}
388-
389-
return this.packageManager.getDeclarationsInPackage(packageName, {
390-
nodeType: referenceType,
391-
});
392-
}
393-
394-
private builtinDeclarations(referenceType: string): AstNodeDescription[] {
395-
return this.packageManager.getDeclarationsInPackageOrSubpackage('safeds', {
396-
nodeType: referenceType,
397-
hideInternal: true,
398-
});
399-
}
400403
}

tests/resources/scoping/annotation calls/across files/main with qualified import.sdstest

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package tests.scoping.annotationCalls.acrossFiles
22

33
from safeds.scoping.annotationCalls.acrossFiles import MyAnnotation
4-
from tests.scoping.annotationCalls.acrossFiles.other import AnnotationInAnotherPackage, Annotation2InAnotherPackage
4+
from tests.scoping.annotationCalls.acrossFiles.other import AnnotationInAnotherPackage, Annotation2InAnotherPackage, NotAnAnnotation
55

66
// $TEST$ references safeds_MyAnnotation
77
@»MyAnnotation«
@@ -18,6 +18,9 @@ from tests.scoping.annotationCalls.acrossFiles.other import AnnotationInAnotherP
1818
// $TEST$ references other_Annotation2InAnotherPackage
1919
@»Annotation2InAnotherPackage«
2020

21+
// $TEST$ unresolved
22+
@»NotAnAnnotation«
23+
2124
// $TEST$ unresolved
2225
@»AnnotationWithoutPackage«
2326
pipeline myPipeline {}

tests/resources/scoping/annotation calls/across files/resource other package.sdstest

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ annotation »AnnotationInAnotherPackage«
88

99
// $TEST$ target other_Annotation2InAnotherPackage
1010
annotation »Annotation2InAnotherPackage«
11+
12+
// $TEST$ target other_NotAnAnnotation
13+
class »NotAnAnnotation«

tests/resources/scoping/named types/across files/to global classes/main with qualified import.sdstest

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package tests.scoping.namedTypes.acrossFiles.toGlobalClasses
22

33
from safeds.scoping.namedTypes.acrossFiles.toGlobalClasses import MyClass
4-
from tests.scoping.namedTypes.acrossFiles.toGlobalClasses.other import ClassInAnotherPackage, Class2InAnotherPackage
4+
from tests.scoping.namedTypes.acrossFiles.toGlobalClasses.other import ClassInAnotherPackage, Class2InAnotherPackage, notANamedTypeDeclaration
55

66
segment mySegment(
77
// $TEST$ references safeds_MyClass
@@ -20,5 +20,8 @@ segment mySegment(
2020
p5: »Class2InAnotherPackage«,
2121

2222
// $TEST$ unresolved
23-
p6: »ClassWithoutPackage«,
23+
p6: »notANamedTypeDeclaration«,
24+
25+
// $TEST$ unresolved
26+
p7: »ClassWithoutPackage«,
2427
) {}

tests/resources/scoping/named types/across files/to global classes/resource other package.sdstest

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ class »ClassInAnotherPackage«
88

99
// $TEST$ target other_Class2InAnotherPackage
1010
class »Class2InAnotherPackage«
11+
12+
// $TEST$ target other_notANamedTypeDeclaration
13+
fun »notANamedTypeDeclaration«()

tests/resources/scoping/named types/across files/to global enums/main with qualified import.sdstest

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package tests.scoping.namedTypes.acrossFiles.toGlobalEnums
22

33
from safeds.scoping.namedTypes.acrossFiles.toGlobalEnums import MyEnum
4-
from tests.scoping.namedTypes.acrossFiles.toGlobalEnums.other import EnumInAnotherPackage, Enum2InAnotherPackage
4+
from tests.scoping.namedTypes.acrossFiles.toGlobalEnums.other import EnumInAnotherPackage, Enum2InAnotherPackage, notANamedTypeDeclaration
55

66
segment mySegment(
77
// $TEST$ references safeds_MyEnum
@@ -20,5 +20,8 @@ segment mySegment(
2020
p5: »Enum2InAnotherPackage«,
2121

2222
// $TEST$ unresolved
23-
p6: »EnumWithoutPackage«,
23+
p6: »notANamedTypeDeclaration«,
24+
25+
// $TEST$ unresolved
26+
p7: »EnumWithoutPackage«,
2427
) {}

tests/resources/scoping/named types/across files/to global enums/resource other package.sdstest

+3
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ enum »EnumInAnotherPackage«
88

99
// $TEST$ target other_Enum2InAnotherPackage
1010
enum »Enum2InAnotherPackage«
11+
12+
// $TEST$ target other_notANamedTypeDeclaration
13+
fun »notANamedTypeDeclaration«()

0 commit comments

Comments
 (0)