diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 021b8c6147d47d42d07c2c95ddb6e38fa421e3f7..b47ff09f704ff798f08c2f74b964a72b4f48ba63 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -23,6 +23,7 @@ #include "varbinder/ETSBinder.h" #include "checker/types/ets/etsPartialTypeParameter.h" #include "checker/types/ets/etsAwaitedType.h" +#include "compiler/lowering/util.h" #include "util/nameMangler.h" #include @@ -685,6 +686,8 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ir::MethodDefinition *nullishAccessor = accessor->Clone(ProgramAllocator(), interface->Body()); + nullishAccessor->SetRange(accessor->Range()); + nullishAccessor->Function()->SetRange(accessor->Function()->Range()); auto *decl = ProgramAllocator()->New(ProgramAllocator(), nullishAccessor->Id()->Name(), nullishAccessor); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index b661e39c240d8a314f94501799c3fef224d70733..c9ff3a8b16d87d85f9b005199b9bca3aa0c2bd38 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -21,6 +21,7 @@ #include "checker/types/ets/etsAsyncFuncReturnType.h" #include "checker/types/ets/etsEnumType.h" #include "compiler/lowering/phase.h" +#include "util/nameMangler.h" #include "ir/statements/annotationDeclaration.h" namespace ark::es2panda::checker { @@ -580,7 +581,7 @@ void ETSObjectType::ToString(std::stringstream &ss, bool precise) const { if (IsPartial()) { ss << "Partial" << compiler::Signatures::GENERIC_BEGIN; - baseType_->ToString(ss, precise); + ss << util::NameMangler::GetInstance()->GetOriginalClassNameFromPartial(name_.Mutf8()); ss << compiler::Signatures::GENERIC_END; return; } @@ -1446,7 +1447,7 @@ void ETSObjectType::CheckAndInstantiateProperties() const return; } - TypeStackElement tse {checker, this, {{diagnostic::CYCLIC_INHERITANCE, {this->Name()}}}, declNode->Start()}; + TypeStackElement tse {checker, this, {{diagnostic::CIRCULAR_DEPENDENCY, {this->Name()}}}, declNode->Start()}; if (tse.HasTypeError()) { return; } diff --git a/ets2panda/test/ast/compiler/ets/broken_partial_type.ets b/ets2panda/test/ast/compiler/ets/broken_partial_type.ets new file mode 100644 index 0000000000000000000000000000000000000000..f43faf7fa2438620fa8866acd2acf3eaf43f2231 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/broken_partial_type.ets @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum Kind { + A = "A", + B = "B" +} + +interface Entity { + kind: () => Kind +} + +interface EntityA extends Entity { + kind: () => Kind.A +} + +interface EntityB extends Entity { + kind: () => Kind.B +} + +type EntityUnion = EntityA | EntityB + +function createEntityA(): EntityUnion { + const entity: Partial = {} + return entity as EntityUnion +} + + +/* @@? 26:3 Error TypeError: kind(): () => *ERROR_TYPE*|undefined in Partial cannot override kind(): () => Kind|undefined in Partial because overriding return type is not compatible with the other return type. */ +/* @@? 26:3 Error TypeError: Method kind(): () => *ERROR_TYPE*|undefined in Partial not overriding any method */ +/* @@? 26:3 Error TypeError: kind(): () => *ERROR_TYPE* in EntityA cannot override kind(): () => Kind in Entity because overriding return type is not compatible with the other return type. */ +/* @@? 26:3 Error TypeError: Method kind(): () => *ERROR_TYPE* in EntityA not overriding any method */ +/* @@? 26:20 Error TypeError: 'A' type does not exist. */ +/* @@? 30:3 Error TypeError: kind(): () => *ERROR_TYPE* in EntityB cannot override kind(): () => Kind in Entity because overriding return type is not compatible with the other return type. */ +/* @@? 30:3 Error TypeError: Method kind(): () => *ERROR_TYPE* in EntityB not overriding any method */ +/* @@? 30:20 Error TypeError: 'B' type does not exist. */ diff --git a/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets b/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets index 467fc6d5c7b25403cb1a3d5aa68cbb05d1a27778..a7bb4cc136be5cf3d8292fc2a3adf98291cbeb08 100644 --- a/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets +++ b/ets2panda/test/ast/compiler/ets/circular_inheritance_parameter.ets @@ -17,5 +17,5 @@ class D{ f7(x: string, y: D.f7){} } -/* @@? 16:8 Error TypeError: Cyclic inheritance involving D. */ -/* @@? 17:22 Error TypeError: 'f7' type does not exist. */ +/* @@? 16:8 Error TypeError: Circular dependency detected for identifier: D */ +/* @@? 17:22 Error TypeError: 'f7' type does not exist. */ diff --git a/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets b/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets index f500f49c6ead8d9ea094ce644cc46358622f75a2..622f2e74d6e20e856c1d1254502b95821c663357 100644 --- a/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets +++ b/ets2panda/test/ast/parser/ets/partialGenericInterface_2.ets @@ -35,5 +35,5 @@ function foa(b: Partial>): void { /* @@ label */foo(/* @@ label1 */b); } -/* @@@ label1 Error TypeError: Type 'Partial>' is not compatible with type 'Partial>' at index 1 */ -/* @@@ label Error TypeError: No matching call signature for foo(Partial>) */ +/* @@? 35:16 Error TypeError: No matching call signature for foo(Partial) */ +/* @@? 35:35 Error TypeError: Type 'Partial' is not compatible with type 'Partial' at index 1 */ diff --git a/ets2panda/util/nameMangler.cpp b/ets2panda/util/nameMangler.cpp index 4880ca481d7a2ac48e678fe57979661061b7f146..70e138917d88ad38c9a6c703565b2e39bf1b6bac 100644 --- a/ets2panda/util/nameMangler.cpp +++ b/ets2panda/util/nameMangler.cpp @@ -98,4 +98,25 @@ std::string NameMangler::AppendToAnnotationName(const std::string &annotationNam return annotationName + "-" + secondPart; } + +std::string NameMangler::GetOriginalClassNameFromPartial(const std::string &partialName) +{ + const std::string partialSuffix = "$partial"; + + if (partialName.length() <= partialSuffix.length()) { + return ""; + } + + size_t suffixPos = partialName.rfind(partialSuffix); + if (suffixPos == std::string::npos) { + return ""; + } + + // Check if the suffix is at the end of the string + if (suffixPos + partialSuffix.length() != partialName.length()) { + return ""; + } + + return partialName.substr(0, suffixPos); +} } // namespace ark::es2panda::util diff --git a/ets2panda/util/nameMangler.h b/ets2panda/util/nameMangler.h index c79060a7656446df4be8972822040c444a077c3e..bfc589d79954bbc9188bdf2d7301a96ec99b7700 100644 --- a/ets2panda/util/nameMangler.h +++ b/ets2panda/util/nameMangler.h @@ -48,6 +48,8 @@ public: std::string CreateMangledNameForAnnotation(const std::string &baseName, const std::string &annotationName); std::string AppendToAnnotationName(const std::string &annotationName, const std::string &secondPart); + std::string GetOriginalClassNameFromPartial(const std::string &partialName); + private: NameMangler() = default; };