diff --git a/ets2panda/compiler/lowering/ets/lateInitialization.cpp b/ets2panda/compiler/lowering/ets/lateInitialization.cpp index 87e878ac135099f51be5e96788c838b633bcc6bc..8a4574d8518c24e5feecc5117f7d3b6647e9611c 100644 --- a/ets2panda/compiler/lowering/ets/lateInitialization.cpp +++ b/ets2panda/compiler/lowering/ets/lateInitialization.cpp @@ -19,14 +19,58 @@ #include "checker/ETSchecker.h" #include "compiler/lowering/util.h" +#include "ir/astNode.h" #include "ir/ets/etsUnionType.h" namespace ark::es2panda::compiler { using AstNodePtr = ir::AstNode *; -ir::ClassProperty *TransformerClassProperty(public_lib::Context *ctx, ir::ClassProperty *property) +static void CopyOverriddenDefiniteInitializer(public_lib::Context *ctx, ir::AstNode *node) { + auto allocator = ctx->allocator; + ir::ClassProperty *property = node->AsClassProperty(); + + if (!node->Parent()->IsClassDefinition() || node->Parent()->AsClassDefinition()->Super() == nullptr) { + return; + } + + auto super = node->Parent()->AsClassDefinition()->Super(); + if (!super->IsETSTypeReference()) { + return; + } + + auto superClass = compiler::DeclarationFromIdentifier(super->AsETSTypeReference()->Part()->Name()->AsIdentifier()); + if (superClass == nullptr) { + return; + } + auto propertyName = property->Key()->AsIdentifier()->Name().Mutf8(); + + auto overridedProperty = superClass->FindChild([propertyName](ir::AstNode *n) { + return n->IsClassProperty() && n->AsClassProperty()->Key()->AsIdentifier()->Name().Is(propertyName); + }); + if (overridedProperty == nullptr) { + return; + } + + ir::Expression *baseVal = overridedProperty->AsClassProperty()->Value(); + if (baseVal == nullptr) { + return; + } + + ir::Expression *clonedExpr = baseVal->Clone(allocator, property)->AsExpression(); + ES2PANDA_ASSERT(clonedExpr != nullptr); + + if (baseVal->TsType() != nullptr) { + clonedExpr->SetTsType(baseVal->TsType()); + } + + property->SetValue(clonedExpr); +} + +static ir::ClassProperty *TransformerClassProperty(public_lib::Context *ctx, ir::AstNode *node) +{ + ir::ClassProperty *property = node->AsClassProperty(); auto checker = ctx->GetChecker()->AsETSChecker(); auto allocator = ctx->allocator; // Note: This code will be excluded after primitive type refactoring @@ -43,6 +87,8 @@ ir::ClassProperty *TransformerClassProperty(public_lib::Context *ctx, ir::ClassP property->SetTsType(annotationType); property->Key()->Variable()->SetTsType(annotationType); property->ClearModifier(ir::ModifierFlags::DEFINITE); + CopyOverriddenDefiniteInitializer(ctx, node); + return property; } diff --git a/ets2panda/test/ast/compiler/ets/late_initialization_default_base_value.ets b/ets2panda/test/ast/compiler/ets/late_initialization_default_base_value.ets new file mode 100644 index 0000000000000000000000000000000000000000..3ec39bab517968ee5915fe9260402a45f4962cd2 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/late_initialization_default_base_value.ets @@ -0,0 +1,28 @@ +/* + * 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. + */ + +class Base { + field: long = 5 +} + +class A extends Base { + override field!: long +} + +function main(): void{ + let a: Base = new A() + arktest.assertTrue(a.field instanceof long) + arktest.assertEQ(a.field, 5) +} \ No newline at end of file