From 167ecf43d4a9e399ca31f3b4c73edce9c3fcd2f3 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sat, 7 Oct 2023 21:56:55 +0200 Subject: [PATCH 1/3] feat: scoping for own instance members of classes --- src/language/grammar/safe-ds.langium | 4 +- .../scoping/safe-ds-scope-provider.ts | 51 ++++++++++--------- src/language/typing/model.ts | 15 ++++++ .../instance attributes/main.sdstest | 44 ++++++++++++++++ .../instance methods/main.sdstest | 44 ++++++++++++++++ .../main.sdstest | 0 .../main.sdstest | 0 .../main.sdstest | 0 .../main.sdstest | 0 .../unnecessary safe access/main.sdstest | 9 ++++ 10 files changed, 140 insertions(+), 27 deletions(-) rename tests/resources/scoping/member accesses/to results/{skip-of block lambdas (matching member) => of block lambdas (matching member)}/main.sdstest (100%) rename tests/resources/scoping/member accesses/to results/{skip-of callable types (matching member) => of callable types (matching member)}/main.sdstest (100%) rename tests/resources/scoping/member accesses/to results/{skip-of functions (matching member) => of functions (matching member)}/main.sdstest (100%) rename tests/resources/scoping/member accesses/to results/{skip-of segments (matching member) => of segments (matching member)}/main.sdstest (100%) diff --git a/src/language/grammar/safe-ds.langium b/src/language/grammar/safe-ds.langium index a97cfb619..6806c5f2b 100644 --- a/src/language/grammar/safe-ds.langium +++ b/src/language/grammar/safe-ds.langium @@ -685,10 +685,10 @@ SdsChainedExpression returns SdsExpression: {SdsCall.receiver=current} argumentList=SdsCallArgumentList - | {SdsIndexedAccess.receiver=current} + | {SdsIndexedAccess.receiver=current} '[' index=SdsExpression ']' - | {SdsMemberAccess.receiver=current} + | {SdsMemberAccess.receiver=current} (isNullSafe?='?')? '.' member=SdsReference diff --git a/src/language/scoping/safe-ds-scope-provider.ts b/src/language/scoping/safe-ds-scope-provider.ts index eb45363b0..a3fdfe139 100644 --- a/src/language/scoping/safe-ds-scope-provider.ts +++ b/src/language/scoping/safe-ds-scope-provider.ts @@ -67,6 +67,7 @@ import { SafeDsServices } from '../safe-ds-module.js'; import { SafeDsTypeComputer } from '../typing/safe-ds-type-computer.js'; import { SafeDsPackageManager } from '../workspace/safe-ds-package-manager.js'; import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js'; +import { ClassType, EnumVariantType } from '../typing/model.js'; export class SafeDsScopeProvider extends DefaultScopeProvider { private readonly astReflection: AstReflection; @@ -176,13 +177,13 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { // Static access const declaration = this.getUniqueReferencedDeclarationForExpression(node.receiver); if (isSdsClass(declaration)) { - return this.createScopeForNodes(classMembersOrEmpty(declaration, isStatic)); - - // val superTypeMembers = receiverDeclaration.superClassMembers() - // .filter { it.isStatic() } - // .toList() + const ownStaticMembers = classMembersOrEmpty(declaration, isStatic); + // val superTypeMembers = receiverDeclaration.superClassMembers() + // .filter { it.isStatic() } + // .toList() // - // return Scopes.scopeFor(members, Scopes.scopeFor(superTypeMembers)) + // return Scopes.scopeFor(ownStaticMembers, Scopes.scopeFor(superTypeMembers)) + return this.createScopeForNodes(ownStaticMembers); } else if (isSdsEnum(declaration)) { return this.createScopeForNodes(enumVariantsOrEmpty(declaration)); } @@ -193,9 +194,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { const callable = this.nodeMapper.callToCallableOrUndefined(node.receiver); const results = abstractResultsOrEmpty(callable); - if (results.length === 0) { - return EMPTY_SCOPE; - } else if (results.length > 1) { + if (results.length > 1) { return this.createScopeForNodes(results); } else { // If there is only one result, it can be accessed by name but members of the result with the same name @@ -204,22 +203,24 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { } } - // // Members - // val type = (receiver.type() as? NamedType) ?: return resultScope - // - // return when { - // type.isNullable && !context.isNullSafe -> resultScope - // type is ClassType -> { - // val members = type.sdsClass.classMembersOrEmpty().filter { !it.isStatic() } - // val superTypeMembers = type.sdsClass.superClassMembers() - // .filter { !it.isStatic() } - // .toList() - // - // Scopes.scopeFor(members, Scopes.scopeFor(superTypeMembers, resultScope)) - // } - // type is EnumVariantType -> Scopes.scopeFor(type.sdsEnumVariant.parametersOrEmpty()) - // else -> resultScope - // } + // Members + let receiverType = this.typeComputer.computeType(node.receiver).unwrap(); + if (receiverType.isNullable && !node.isNullSafe) { + return resultScope; + } + + if (receiverType instanceof ClassType) { + const ownInstanceMembers = classMembersOrEmpty(receiverType.sdsClass, (it) => !isStatic(it)); + // val superTypeMembers = type.sdsClass.superClassMembers() + // .filter { !it.isStatic() } + // .toList() + // + // Scopes.scopeFor(members, Scopes.scopeFor(superTypeMembers, resultScope)) + return this.createScopeForNodes(ownInstanceMembers, resultScope); + } else if (receiverType instanceof EnumVariantType) { + // Scopes.scopeFor(type.sdsEnumVariant.parametersOrEmpty()) + return resultScope; + } return resultScope; } diff --git a/src/language/typing/model.ts b/src/language/typing/model.ts index 16e190d7d..d24de68a5 100644 --- a/src/language/typing/model.ts +++ b/src/language/typing/model.ts @@ -12,6 +12,10 @@ import { export abstract class Type { abstract isNullable: boolean; + unwrap(): Type { + return this; + } + abstract copyWithNullability(isNullable: boolean): Type; abstract equals(other: Type): boolean; @@ -110,6 +114,17 @@ export class NamedTupleType extends Type { return this.entries.length; } + /** + * If this only has one entry, returns its type. Otherwise, returns this. + */ + override unwrap(): Type { + if (this.entries.length === 1) { + return this.entries[0].type; + } + + return this; + } + override copyWithNullability(_isNullable: boolean): NamedTupleType { return this; } diff --git a/tests/resources/scoping/member accesses/to class members/instance attributes/main.sdstest b/tests/resources/scoping/member accesses/to class members/instance attributes/main.sdstest index a5f3b8379..f7699f7a9 100644 --- a/tests/resources/scoping/member accesses/to class members/instance attributes/main.sdstest +++ b/tests/resources/scoping/member accesses/to class members/instance attributes/main.sdstest @@ -49,13 +49,57 @@ class MyClass { class AnotherClass +fun nullableMyClass() -> result: MyClass? + pipeline myPipeline { + // $TEST$ references myInstanceAttribute + val myClass = MyClass(); + myClass.»myInstanceAttribute«; + + + // $TEST$ references redeclaredAsInstanceAttribute + MyClass().»redeclaredAsInstanceAttribute«; + + // $TEST$ references redeclaredAsStaticAttribute + MyClass().»redeclaredAsStaticAttribute«; + + // $TEST$ references redeclaredAsNestedClass + MyClass().»redeclaredAsNestedClass«; + + // $TEST$ references redeclaredAsNestedEnum + MyClass().»redeclaredAsNestedEnum«; + + // $TEST$ references redeclaredAsInstanceMethod + MyClass().»redeclaredAsInstanceMethod«; + + // $TEST$ references redeclaredAsStaticMethod + MyClass().»redeclaredAsStaticMethod«; + + // $TEST$ references declaredPreviouslyAsStaticAttribute + MyClass().»declaredPreviouslyAsStaticAttribute«; + + // $TEST$ references declaredPreviouslyAsNestedClass + MyClass().»declaredPreviouslyAsNestedClass«; + + // $TEST$ references declaredPreviouslyAsNestedEnum + MyClass().»declaredPreviouslyAsNestedEnum«; + + // $TEST$ references declaredPreviouslyAsStaticMethod + MyClass().»declaredPreviouslyAsStaticMethod«; + + // $TEST$ references myInstanceAttribute + nullableMyClass()?.»myInstanceAttribute«; + + // $TEST$ unresolved MyClass.»myInstanceAttribute«; // $TEST$ unresolved AnotherClass().»myInstanceAttribute«; + // $TEST$ unresolved + nullableMyClass().»myInstanceAttribute«; + // $TEST$ unresolved unresolved.»myInstanceAttribute«; diff --git a/tests/resources/scoping/member accesses/to class members/instance methods/main.sdstest b/tests/resources/scoping/member accesses/to class members/instance methods/main.sdstest index 695e6ba1e..693bdbf49 100644 --- a/tests/resources/scoping/member accesses/to class members/instance methods/main.sdstest +++ b/tests/resources/scoping/member accesses/to class members/instance methods/main.sdstest @@ -49,13 +49,57 @@ class MyClass { class AnotherClass +fun nullableMyClass() -> result: MyClass? + pipeline myPipeline { + // $TEST$ references myInstanceMethod + val myClass = MyClass(); + myClass.»myInstanceMethod«(); + + + // $TEST$ references redeclaredAsInstanceAttribute + MyClass().»redeclaredAsInstanceAttribute«(); + + // $TEST$ references redeclaredAsStaticAttribute + MyClass().»redeclaredAsStaticAttribute«(); + + // $TEST$ references redeclaredAsNestedClass + MyClass().»redeclaredAsNestedClass«(); + + // $TEST$ references redeclaredAsNestedEnum + MyClass().»redeclaredAsNestedEnum«(); + + // $TEST$ references redeclaredAsInstanceMethod + MyClass().»redeclaredAsInstanceMethod«(); + + // $TEST$ references redeclaredAsStaticMethod + MyClass().»redeclaredAsStaticMethod«(); + + // $TEST$ references declaredPreviouslyAsStaticAttribute + MyClass().»declaredPreviouslyAsStaticAttribute«(); + + // $TEST$ references declaredPreviouslyAsNestedClass + MyClass().»declaredPreviouslyAsNestedClass«(); + + // $TEST$ references declaredPreviouslyAsNestedEnum + MyClass().»declaredPreviouslyAsNestedEnum«(); + + // $TEST$ references declaredPreviouslyAsStaticMethod + MyClass().»declaredPreviouslyAsStaticMethod«(); + + // $TEST$ references myInstanceMethod + nullableMyClass()?.»myInstanceMethod«(); + + // $TEST$ unresolved MyClass.»myInstanceMethod«; // $TEST$ unresolved AnotherClass().»myInstanceMethod«; + // $TEST$ unresolved + nullableMyClass().»myInstanceAttribute«; + // $TEST$ unresolved unresolved.»myInstanceMethod«; diff --git a/tests/resources/scoping/member accesses/to results/skip-of block lambdas (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest similarity index 100% rename from tests/resources/scoping/member accesses/to results/skip-of block lambdas (matching member)/main.sdstest rename to tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest diff --git a/tests/resources/scoping/member accesses/to results/skip-of callable types (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest similarity index 100% rename from tests/resources/scoping/member accesses/to results/skip-of callable types (matching member)/main.sdstest rename to tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest diff --git a/tests/resources/scoping/member accesses/to results/skip-of functions (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest similarity index 100% rename from tests/resources/scoping/member accesses/to results/skip-of functions (matching member)/main.sdstest rename to tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest diff --git a/tests/resources/scoping/member accesses/to results/skip-of segments (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest similarity index 100% rename from tests/resources/scoping/member accesses/to results/skip-of segments (matching member)/main.sdstest rename to tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest diff --git a/tests/resources/validation/style/unnecessary safe access/main.sdstest b/tests/resources/validation/style/unnecessary safe access/main.sdstest index c1ad2d81c..89a251cfb 100644 --- a/tests/resources/validation/style/unnecessary safe access/main.sdstest +++ b/tests/resources/validation/style/unnecessary safe access/main.sdstest @@ -1,10 +1,19 @@ package tests.validation.style.unnecessarySafeAccess +class MyClass + +fun nullableMyClass() -> result: MyClass? + pipeline test { // $TEST$ info "The receiver is never null, so the safe access is unnecessary." »1?.toString«(); + // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." »null?.toString«(); + + // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." + »nullableMyClass()?.toString«(); + // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." »unresolved?.toString«(); } From 753812009771798909aa5e6c066e3e127ef0ea8f Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sat, 7 Oct 2023 22:19:46 +0200 Subject: [PATCH 2/3] fix: incorrect info about non-nullable left-hand side of safe access --- src/language/scoping/safe-ds-scope-provider.ts | 2 +- src/language/typing/safe-ds-type-computer.ts | 2 +- .../typing/expressions/calls/of block lambdas/main.sdstest | 2 +- .../typing/expressions/calls/of callable types/main.sdstest | 2 +- .../expressions/calls/of expression lambdas/main.sdstest | 2 +- .../typing/expressions/calls/of functions/main.sdstest | 2 +- .../typing/expressions/calls/of segments/main.sdstest | 2 +- .../validation/style/unnecessary safe access/main.sdstest | 3 +++ 8 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/language/scoping/safe-ds-scope-provider.ts b/src/language/scoping/safe-ds-scope-provider.ts index a3fdfe139..c67886985 100644 --- a/src/language/scoping/safe-ds-scope-provider.ts +++ b/src/language/scoping/safe-ds-scope-provider.ts @@ -204,7 +204,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { } // Members - let receiverType = this.typeComputer.computeType(node.receiver).unwrap(); + let receiverType = this.typeComputer.computeType(node.receiver); if (receiverType.isNullable && !node.isNullSafe) { return resultScope; } diff --git a/src/language/typing/safe-ds-type-computer.ts b/src/language/typing/safe-ds-type-computer.ts index ebdf168cd..3ee0abfd8 100644 --- a/src/language/typing/safe-ds-type-computer.ts +++ b/src/language/typing/safe-ds-type-computer.ts @@ -104,7 +104,7 @@ export class SafeDsTypeComputer { const documentUri = getDocument(node).uri.toString(); const nodePath = this.astNodeLocator.getAstNodePath(node); const key = `${documentUri}~${nodePath}`; - return this.typeCache.get(key, () => this.doComputeType(node)); + return this.typeCache.get(key, () => this.doComputeType(node).unwrap()); } // fun SdsAbstractObject.hasPrimitiveType(): Boolean { diff --git a/tests/resources/typing/expressions/calls/of block lambdas/main.sdstest b/tests/resources/typing/expressions/calls/of block lambdas/main.sdstest index c6c4b418c..eacbaeceb 100644 --- a/tests/resources/typing/expressions/calls/of block lambdas/main.sdstest +++ b/tests/resources/typing/expressions/calls/of block lambdas/main.sdstest @@ -1,7 +1,7 @@ package tests.typing.expressions.calls.ofBlockLambdas pipeline myPipeline { - // $TEST$ serialization (r: String) + // $TEST$ serialization String »(() { yield r = ""; })()«; diff --git a/tests/resources/typing/expressions/calls/of callable types/main.sdstest b/tests/resources/typing/expressions/calls/of callable types/main.sdstest index 032cbec00..4cc957bb3 100644 --- a/tests/resources/typing/expressions/calls/of callable types/main.sdstest +++ b/tests/resources/typing/expressions/calls/of callable types/main.sdstest @@ -4,7 +4,7 @@ segment mySegment( p1: () -> r: String, p2: () -> (r: String, s: Int) ) { - // $TEST$ serialization (r: String) + // $TEST$ serialization String »p1()«; // $TEST$ serialization (r: String, s: Int) diff --git a/tests/resources/typing/expressions/calls/of expression lambdas/main.sdstest b/tests/resources/typing/expressions/calls/of expression lambdas/main.sdstest index 7866aa463..d634db366 100644 --- a/tests/resources/typing/expressions/calls/of expression lambdas/main.sdstest +++ b/tests/resources/typing/expressions/calls/of expression lambdas/main.sdstest @@ -1,6 +1,6 @@ package tests.typing.expressions.calls.ofExpressionLambdas pipeline myPipeline { - // $TEST$ serialization (result: Int) + // $TEST$ serialization Int »(() -> 1)()«; } diff --git a/tests/resources/typing/expressions/calls/of functions/main.sdstest b/tests/resources/typing/expressions/calls/of functions/main.sdstest index e044b7e0a..dec1e1e1d 100644 --- a/tests/resources/typing/expressions/calls/of functions/main.sdstest +++ b/tests/resources/typing/expressions/calls/of functions/main.sdstest @@ -4,7 +4,7 @@ fun f1() -> r: String fun f2() -> (r: String, s: Int) pipeline myPipeline { - // $TEST$ serialization (r: String) + // $TEST$ serialization String »f1()«; // $TEST$ serialization (r: String, s: Int) diff --git a/tests/resources/typing/expressions/calls/of segments/main.sdstest b/tests/resources/typing/expressions/calls/of segments/main.sdstest index 99f805821..4c8861ea4 100644 --- a/tests/resources/typing/expressions/calls/of segments/main.sdstest +++ b/tests/resources/typing/expressions/calls/of segments/main.sdstest @@ -9,7 +9,7 @@ segment s2() -> (r: String, s: Int) { } pipeline myPipeline { - // $TEST$ serialization (r: String) + // $TEST$ serialization String »s1()«; // $TEST$ serialization (r: String, s: Int) diff --git a/tests/resources/validation/style/unnecessary safe access/main.sdstest b/tests/resources/validation/style/unnecessary safe access/main.sdstest index 89a251cfb..35154efb8 100644 --- a/tests/resources/validation/style/unnecessary safe access/main.sdstest +++ b/tests/resources/validation/style/unnecessary safe access/main.sdstest @@ -14,6 +14,9 @@ pipeline test { // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." »nullableMyClass()?.toString«(); + // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." + nullableMyClass()»?.toString«(); // Langium currently computes the wrong range for a member access + // $TEST$ no info "The receiver is never null, so the safe access is unnecessary." »unresolved?.toString«(); } From 6cdabda19e0e95ee8cf095316e10b1b2dec469c0 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sat, 7 Oct 2023 22:41:23 +0200 Subject: [PATCH 3/3] feat: scoping for parameters of enum variants --- .../scoping/safe-ds-scope-provider.ts | 4 +- .../main.sdstest | 45 +++++++++++++++++++ .../main.sdstest | 16 ++++++- .../main.sdstest | 14 +++++- .../main.sdstest | 13 +++++- .../main.sdstest | 13 +++++- 6 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 tests/resources/scoping/member accesses/to parameter of enum variants/main.sdstest diff --git a/src/language/scoping/safe-ds-scope-provider.ts b/src/language/scoping/safe-ds-scope-provider.ts index c67886985..9c9ec45a2 100644 --- a/src/language/scoping/safe-ds-scope-provider.ts +++ b/src/language/scoping/safe-ds-scope-provider.ts @@ -218,8 +218,8 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { // Scopes.scopeFor(members, Scopes.scopeFor(superTypeMembers, resultScope)) return this.createScopeForNodes(ownInstanceMembers, resultScope); } else if (receiverType instanceof EnumVariantType) { - // Scopes.scopeFor(type.sdsEnumVariant.parametersOrEmpty()) - return resultScope; + const parameters = parametersOrEmpty(receiverType.sdsEnumVariant); + return this.createScopeForNodes(parameters, resultScope); } return resultScope; diff --git a/tests/resources/scoping/member accesses/to parameter of enum variants/main.sdstest b/tests/resources/scoping/member accesses/to parameter of enum variants/main.sdstest new file mode 100644 index 000000000..2ba689a18 --- /dev/null +++ b/tests/resources/scoping/member accesses/to parameter of enum variants/main.sdstest @@ -0,0 +1,45 @@ +package tests.scoping.memberAccesses.toParametersOfEnumVariants + +enum MyEnum { + MyEnumVariant( + // $TEST$ target param + »param«: Int, + + // $TEST$ target redeclared + »redeclared«: Int, + redeclared: Int, + ) + + MyOtherEnumVariant +} + +enum MyOtherEnum { + MyEnumVariant +} + +pipeline myPipeline { + // $TEST$ references param + MyEnum.MyEnumVariant().»param«; + + // $TEST$ references redeclared + MyEnum.MyEnumVariant().»redeclared«; + + + // $TEST$ unresolved + MyOtherEnum.MyEnumVariant.»param«; + + // $TEST$ unresolved + MyEnum.MyOtherEnumVariant().»param«; + + // $TEST$ unresolved + MyOtherEnum.MyEnumVariant().»param«; + + // $TEST$ unresolved + MyEnum.MyEnumVariant().»unresolved«; + + // $TEST$ unresolved + MyEnum.unresolved().»param«; + + // $TEST$ unresolved + unresolved.MyEnumVariant().»param«; +} diff --git a/tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest index fb53b4374..b197f34bc 100644 --- a/tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest +++ b/tests/resources/scoping/member accesses/to results/of block lambdas (matching member)/main.sdstest @@ -5,11 +5,23 @@ class MyClass() { attr »result«: Int } +enum MyEnum { + // $TEST$ target MyEnum_result + MyEnumVariant(»result«: Int) +} + pipeline myPipeline { - val lambdaWithOneResultWithIdenticalMember = () { + val f1 = () { yield result = MyClass(); }; + val f2 = () { + yield result = MyEnum.MyEnumVariant(0); + }; + // $TEST$ references MyClass_result - lambdaWithOneResultWithIdenticalMember().»result«; + f1().»result«; + + // $TEST$ references MyEnum_result + f2().»result«; } diff --git a/tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest index 3d14a472b..a7cc1c823 100644 --- a/tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest +++ b/tests/resources/scoping/member accesses/to results/of callable types (matching member)/main.sdstest @@ -5,9 +5,19 @@ class MyClass() { attr »result«: Int } +enum MyEnum { + // $TEST$ target MyEnum_result + MyEnumVariant(»result«: Int) +} + segment mySegment( - callableWithIdenticalMember: () -> result: MyClass + f1: () -> result: MyClass, + f2: () -> result: MyEnum.MyEnumVariant, ) { + // $TEST$ references MyClass_result - callableWithIdenticalMember().»result«; + f1().»result«; + + // $TEST$ references MyEnum_result + f2().»result«; } diff --git a/tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest index 6ac04e80e..263e0eece 100644 --- a/tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest +++ b/tests/resources/scoping/member accesses/to results/of functions (matching member)/main.sdstest @@ -5,9 +5,18 @@ class MyClass() { attr »result«: Int } -fun functionWithOneResultWithIdenticalMember() -> result: MyClass +enum MyEnum { + // $TEST$ target MyEnum_result + MyEnumVariant(»result«: Int) +} + +fun f1() -> result: MyClass +fun f2() -> result: MyEnum.MyEnumVariant pipeline myPipeline { // $TEST$ references MyClass_result - functionWithOneResultWithIdenticalMember().»result«; + f1().»result«; + + // $TEST$ references MyEnum_result + f2().»result«; } diff --git a/tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest b/tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest index c90dae517..79463aaeb 100644 --- a/tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest +++ b/tests/resources/scoping/member accesses/to results/of segments (matching member)/main.sdstest @@ -5,9 +5,18 @@ class MyClass() { attr »result«: Int } -segment segmentWithOneResultWithIdenticalMember() -> result: MyClass {} +enum MyEnum { + // $TEST$ target MyEnum_result + MyEnumVariant(»result«: Int) +} + +segment s1() -> result: MyClass {} +segment s2() -> result: MyEnum.MyEnumVariant {} pipeline myPipeline { // $TEST$ references MyClass_result - segmentWithOneResultWithIdenticalMember().»result«; + s1().»result«; + + // $TEST$ references MyEnum_result + s2().»result«; }