From 1277bd1f5efe4cf9532d03b656d26b026428b461 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sat, 17 Feb 2024 12:51:48 +0100 Subject: [PATCH] feat: scoping for member accesses if receiver has type parameter type (#889) ### Summary of Changes The scope provider can now handle member accesses where the receiver has type parameter type. This type is replaced by its upper bound, before name resolution continues as before. --- .../scoping/safe-ds-scope-provider.ts | 4 ++- .../on type parameters/main.sdstest | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest diff --git a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts index a0fd47437..d9b080806 100644 --- a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts +++ b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts @@ -71,7 +71,7 @@ import { } from '../helpers/nodeProperties.js'; import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js'; import { SafeDsServices } from '../safe-ds-module.js'; -import { ClassType, EnumVariantType, LiteralType } from '../typing/model.js'; +import { ClassType, EnumVariantType, LiteralType, TypeParameterType } from '../typing/model.js'; import type { SafeDsClassHierarchy } from '../typing/safe-ds-class-hierarchy.js'; import { SafeDsTypeComputer } from '../typing/safe-ds-type-computer.js'; import { SafeDsPackageManager } from '../workspace/safe-ds-package-manager.js'; @@ -227,6 +227,8 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { let receiverType = this.typeComputer.computeType(node.receiver); if (receiverType instanceof LiteralType) { receiverType = this.typeComputer.computeClassTypeForLiteralType(receiverType); + } else if (receiverType instanceof TypeParameterType) { + receiverType = this.typeComputer.computeUpperBound(receiverType); } if (receiverType instanceof ClassType) { diff --git a/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest new file mode 100644 index 000000000..ee0348077 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest @@ -0,0 +1,29 @@ +package tests.scoping.memberAccesses.onTypeParameters + +class C { + // $TEST$ target attribute + attr »a«: Int +} + +class MyClass( + unbounded: Unbounded, + upperBound: UpperBound, + + // $TEST$ unresolved + p1: Any = unbounded.»a«, + // $TEST$ references attribute + p2: Any = upperBound.»a«, +) where { + UpperBound sub C +} { + attr unbounded: Unbounded + attr upperBound: UpperBound +} + +segment mySegment(instance: MyClass) { + // $TEST$ references attribute + instance.unbounded.»a«; + + // $TEST$ references attribute + instance.upperBound.»a«; +}