From 1b0490559bcd9fcb27a498aa0d9595bfc3e745a2 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Sat, 30 Sep 2023 11:53:54 +0200 Subject: [PATCH] feat: allow instance and static members of classes to have the same name (#583) ### Summary of Changes Classes can now have static and instance members with the same name. This better matches the behavior of the scoping mechanism that does not resolve static references to instance members or dynamic references to static members. --- src/language/validation/names.ts | 7 +- .../names/duplicates/in class/main.sdstest | 199 ++++++++++++++---- 2 files changed, 163 insertions(+), 43 deletions(-) diff --git a/src/language/validation/names.ts b/src/language/validation/names.ts index eeed27201..c9557ca2d 100644 --- a/src/language/validation/names.ts +++ b/src/language/validation/names.ts @@ -21,6 +21,7 @@ import { typeParametersOrEmpty, enumVariantsOrEmpty, } from '../helpers/shortcuts.js'; +import { isStatic } from '../helpers/checks.js'; export const CODE_NAME_BLOCK_LAMBDA_PREFIX = 'name/block-lambda-prefix'; export const CODE_NAME_CASING = 'name/casing'; @@ -181,7 +182,11 @@ export const classMustContainUniqueNames = (node: SdsClass, accept: ValidationAc accept, ); - namesMustBeUnique(classMembersOrEmpty(node), (name) => `A member with name '${name}' exists already.`, accept); + const instanceMembers = classMembersOrEmpty(node, (it) => !isStatic(it)); + namesMustBeUnique(instanceMembers, (name) => `An instance member with name '${name}' exists already.`, accept); + + const staticMembers = classMembersOrEmpty(node, isStatic); + namesMustBeUnique(staticMembers, (name) => `A static member with name '${name}' exists already.`, accept); }; export const enumMustContainUniqueNames = (node: SdsEnum, accept: ValidationAcceptor): void => { diff --git a/tests/resources/validation/names/duplicates/in class/main.sdstest b/tests/resources/validation/names/duplicates/in class/main.sdstest index ba178f8db..650707e04 100644 --- a/tests/resources/validation/names/duplicates/in class/main.sdstest +++ b/tests/resources/validation/names/duplicates/in class/main.sdstest @@ -23,104 +23,219 @@ class MyClass1< // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »parameterAndMember«: Int, ) { - // $TEST$ no error r"A member with name '\w*' exists already\." - attr »duplicateAttribute«: Int - // $TEST$ error "A member with name 'duplicateAttribute' exists already." - attr »duplicateAttribute«: Int - // $TEST$ no error r"A member with name '\w*' exists already\." - attr »uniqueAttribute«: Int - - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"An instance member with name '\w*' exists already\." + attr »duplicateInstanceAttribute«: Int + // $TEST$ error "An instance member with name 'duplicateInstanceAttribute' exists already." + attr »duplicateInstanceAttribute«: Int + // $TEST$ no error r"An instance member with name '\w*' exists already\." + attr »uniqueInstanceAttribute«: Int + + // $TEST$ no error r"A static member with name '\w*' exists already\." + static attr »duplicateStaticAttribute«: Int + // $TEST$ error "A static member with name 'duplicateStaticAttribute' exists already." + static attr »duplicateStaticAttribute«: Int + // $TEST$ no error r"A static member with name '\w*' exists already\." + static attr »uniqueStaticAttribute«: Int + + // $TEST$ no error r"A static member with name '\w*' exists already\." class »DuplicateClass« - // $TEST$ error "A member with name 'DuplicateClass' exists already." + // $TEST$ error "A static member with name 'DuplicateClass' exists already." class »DuplicateClass« - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A static member with name '\w*' exists already\." class »UniqueClass« - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A static member with name '\w*' exists already\." enum »DuplicateEnum« - // $TEST$ error "A member with name 'DuplicateEnum' exists already." + // $TEST$ error "A static member with name 'DuplicateEnum' exists already." enum »DuplicateEnum« - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A static member with name '\w*' exists already\." enum »UniqueEnum« - // $TEST$ no error r"A member with name '\w*' exists already\." - fun »duplicateFun«() - // $TEST$ error "A member with name 'duplicateFun' exists already." - fun »duplicateFun«() - // $TEST$ no error r"A member with name '\w*' exists already\." - fun »uniqueFun«() - - // $TEST$ no error r"A member with name '\w*' exists already\." - attr »duplicateMember«: Int - // $TEST$ error "A member with name 'duplicateMember' exists already." - class »duplicateMember« - // $TEST$ error "A member with name 'duplicateMember' exists already." - enum »duplicateMember« - // $TEST$ error "A member with name 'duplicateMember' exists already." - fun »duplicateMember«() + // $TEST$ no error r"An instance member with name '\w*' exists already\." + fun »duplicateInstanceMethod«() + // $TEST$ error "An instance member with name 'duplicateInstanceMethod' exists already." + fun »duplicateInstanceMethod«() + // $TEST$ no error r"An instance member with name '\w*' exists already\." + fun »uniqueInstanceMethod«() + + // $TEST$ no error r"A static member with name '\w*' exists already\." + static fun »duplicateStaticMethod«() + // $TEST$ error "A static member with name 'duplicateStaticMethod' exists already." + static fun »duplicateStaticMethod«() + // $TEST$ no error r"A static member with name '\w*' exists already\." + static fun »uniqueStaticMethod«() + + // $TEST$ no error r"An instance member with name '\w*' exists already\." + attr »duplicateInstanceMember«: Int + // $TEST$ error "An instance member with name 'duplicateInstanceMember' exists already." + fun »duplicateInstanceMember«() + + // $TEST$ no error r"A static member with name '\w*' exists already\." + static attr »duplicateStaticMember«: Int + // $TEST$ error "A static member with name 'duplicateStaticMember' exists already." + class »duplicateStaticMember« + // $TEST$ error "A static member with name 'duplicateStaticMember' exists already." + enum »duplicateStaticMember« + // $TEST$ error "A static member with name 'duplicateStaticMember' exists already." + static fun »duplicateStaticMember«() } class MyClass2< // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »TypeParameterAndMember«, > { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." attr »TypeParameterAndMember«: Int + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »instanceAndStaticMember«: Int + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static attr »instanceAndStaticMember«: Int + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static attr »staticAndInstanceMember«: Int + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »staticAndInstanceMember«: Int } class MyClass3< // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »TypeParameterAndMember«, > { - // $TEST$ no error r"A member with name '\w*' exists already\." - class »TypeParameterAndMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + static attr »TypeParameterAndMember«: Int + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »instanceAndStaticMember«: Int + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + class »instanceAndStaticMember« + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + class »staticAndInstanceMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »staticAndInstanceMember«: Int } class MyClass4< // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »TypeParameterAndMember«, > { - // $TEST$ no error r"A member with name '\w*' exists already\." - enum »TypeParameterAndMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + class »TypeParameterAndMember« + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »instanceAndStaticMember«: Int + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + enum »instanceAndStaticMember« + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + enum »staticAndInstanceMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »staticAndInstanceMember«: Int } class MyClass5< // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »TypeParameterAndMember«, > { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." + enum »TypeParameterAndMember« + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »instanceAndStaticMember«: Int + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static fun »instanceAndStaticMember«() + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static fun »staticAndInstanceMember«() + // $TEST$ no error r"A.*member with name '\w*' exists already\." + attr »staticAndInstanceMember«: Int +} + +class MyClass6< + // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." + »TypeParameterAndMember«, +> { + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »TypeParameterAndMember«() + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »instanceAndStaticMember«() + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static attr »instanceAndStaticMember«: Int + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static attr »staticAndInstanceMember«: Int + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »staticAndInstanceMember«() +} + +class MyClass7< + // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." + »TypeParameterAndMember«, +> { + // $TEST$ no error r"A.*member with name '\w*' exists already\." fun »TypeParameterAndMember«() + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »instanceAndStaticMember«() + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + class »instanceAndStaticMember« + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + class »staticAndInstanceMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »staticAndInstanceMember«() } -class MyClass6( +class MyClass8( // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »parameterAndMember«: Int, ) { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." attr »parameterAndMember«: Int + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »instanceAndStaticMember«() + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + enum »instanceAndStaticMember« + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + enum »staticAndInstanceMember« + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »staticAndInstanceMember«() } -class MyClass7( +class MyClass9( // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »parameterAndMember«: Int, ) { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." class »parameterAndMember« + + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »instanceAndStaticMember«() + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static fun »instanceAndStaticMember«() + + // $TEST$ no error "r"A.*member with name '\w*' exists already\." + static fun »staticAndInstanceMember«() + // $TEST$ no error r"A.*member with name '\w*' exists already\." + fun »staticAndInstanceMember«() } -class MyClass8( +class MyClass10( // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »parameterAndMember«: Int, ) { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." enum »parameterAndMember« } -class MyClass9( +class MyClass11( // $TEST$ no error r"A type parameter or parameter with name '\w*' exists already\." »parameterAndMember«: Int, ) { - // $TEST$ no error r"A member with name '\w*' exists already\." + // $TEST$ no error r"A.*member with name '\w*' exists already\." fun »parameterAndMember«() }