From a5641519740788332944359515a952fe24bd09fc Mon Sep 17 00:00:00 2001 From: Dmitry Pimenov Date: Thu, 10 Jul 2025 18:21:44 +0300 Subject: [PATCH] Fix NS.class field with this Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLJDX Signed-off-by: Dmitry Pimenov --- ets2panda/checker/ETSchecker.h | 2 +- ets2panda/checker/ets/helpers.cpp | 2 +- ets2panda/checker/ets/typeCheckingHelpers.cpp | 22 ++++++------- .../namespace_this_in_field.ets | 32 +++++++++++++++++++ 4 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 ets2panda/test/runtime/ets/namespace_tests/namespace_this_in_field.ets diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index d27cf96faa..111dab64e6 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -1019,7 +1019,7 @@ private: PropertySearchFlags GetSearchFlags(const ir::MemberExpression *memberExpr, const varbinder::Variable *targetRef); PropertySearchFlags GetInitialSearchFlags(const ir::MemberExpression *memberExpr); Type *GetTypeOfSetterGetter([[maybe_unused]] varbinder::Variable *var); - void IterateInVariableContext([[maybe_unused]] varbinder::Variable *const var); + SavedCheckerContext CreateSavedCheckerContext(varbinder::Variable *const var); bool CheckInit(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, checker::Type *annotationType, varbinder::Variable *const bindingVar); void CheckItemCasesConstant(ArenaVector const &cases); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index bf9c6c2c56..3d046a53fd 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -3014,7 +3014,7 @@ void ETSChecker::GenerateGetterSetterPropertyAndMethod(ir::ClassProperty *origin const auto &name = getter->Key()->AsIdentifier()->Name(); ir::MethodDefinition *setter = - !classProp->IsConst() + !classProp->IsConst() && !classProp->IsReadonly() // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ? GenerateDefaultGetterSetter(interfaceProp, classProp, Scope()->AsClassScope(), true, this) : nullptr; diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 52897f93be..b55c1c76d4 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -14,6 +14,7 @@ */ #include "checker/checker.h" +#include "checker/checkerContext.h" #include "checker/ets/wideningConverter.h" #include "checker/types/globalTypesHolder.h" #include "checker/types/gradualType.h" @@ -514,38 +515,36 @@ Type *ETSChecker::CreateSyntheticTypeFromOverload(varbinder::Variable *const var return syntheticFunctionType; } -void ETSChecker::IterateInVariableContext(varbinder::Variable *const var) +SavedCheckerContext ETSChecker::CreateSavedCheckerContext(varbinder::Variable *const var) { // Before computing the given variables type, we have to make a new checker context frame so that the checking is // done in the proper context, and have to enter the scope where the given variable is declared, so reference // resolution works properly - auto *iter = var->Declaration()->Node()->Parent(); - while (iter != nullptr) { + auto constexpr STATUS = CheckerStatus::NO_OPTS; + for (auto *iter = var->Declaration()->Node()->Parent(); iter != nullptr; iter = iter->Parent()) { if (iter->IsMethodDefinition()) { auto *methodDef = iter->AsMethodDefinition(); ES2PANDA_ASSERT(methodDef->TsType()); auto *func = methodDef->Function(); ES2PANDA_ASSERT(func != nullptr); - Context().SetContainingSignature(func->Signature()); - } else if (iter->IsClassDefinition()) { + return SavedCheckerContext(this, STATUS, nullptr, func->Signature()); + } + if (iter->IsClassDefinition()) { auto *classDef = iter->AsClassDefinition(); Type *containingClass {}; - if (classDef->TsType() == nullptr) { containingClass = BuildBasicClassProperties(classDef)->MaybeBaseTypeOfGradualType(); ResolveDeclaredMembersOfObject(containingClass); } else { containingClass = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); } - ES2PANDA_ASSERT(classDef->TsType()); if (!containingClass->IsTypeError()) { - Context().SetContainingClass(containingClass->AsETSObjectType()); + return SavedCheckerContext(this, STATUS, containingClass->AsETSObjectType()); } } - - iter = iter->Parent(); } + return SavedCheckerContext(this, STATUS); } static Type *GetTypeFromVarLikeVariableDeclaration(ETSChecker *checker, varbinder::Variable *const var) @@ -634,9 +633,8 @@ Type *ETSChecker::GetTypeOfVariable(varbinder::Variable *const var) return var->TsType(); } - checker::SavedCheckerContext savedContext(this, CheckerStatus::NO_OPTS); + checker::SavedCheckerContext savedContext = CreateSavedCheckerContext(var); checker::ScopeContext scopeCtx(this, var->GetScope()); - IterateInVariableContext(var); return GetTypeFromVariableDeclaration(var); } diff --git a/ets2panda/test/runtime/ets/namespace_tests/namespace_this_in_field.ets b/ets2panda/test/runtime/ets/namespace_tests/namespace_this_in_field.ets new file mode 100644 index 0000000000..de04c4d919 --- /dev/null +++ b/ets2panda/test/runtime/ets/namespace_tests/namespace_this_in_field.ets @@ -0,0 +1,32 @@ +/* + * 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. + */ + +namespace NS { + export interface I { + readonly p: boolean + } + + export class C implements I { + readonly p: boolean = this.getP() + getP(): boolean { + return true + } + } +} + +function main() { + const c = new NS.C as NS.I + arktest.assertTrue(c.p) +} -- Gitee