diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 9e26143b69d04766ede7873bbab22abb01dd8671..98c134b6c76012a7b3d4aed0b48c33be0cd49657 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -758,6 +758,8 @@ void ETSCompiler::Compile(const ir::CallExpression *expr) const auto const callee = expr->Callee(); checker::Signature *const signature = expr->Signature(); + ES2PANDA_ASSERT(signature != nullptr); + ES2PANDA_ASSERT(!callee->TsType()->IsETSArrowType()); // should have been lowered bool const isStatic = signature->HasSignatureFlag(checker::SignatureFlags::STATIC); @@ -951,7 +953,20 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const } else if (objectType->IsETSUnionType()) { etsg->LoadPropertyByName(expr, objReg, checker::ETSChecker::FormNamedAccessMetadata(expr->PropVar())); } else { - const auto fullName = etsg->FormClassPropReference(objectType->AsETSObjectType(), propName); + auto *id = expr->Property()->AsIdentifier(); + auto *var = id->Variable(); + ES2PANDA_ASSERT(var != nullptr && var->Declaration() != nullptr); + + auto *decl = var->Declaration(); + ES2PANDA_ASSERT(decl->Node() != nullptr); + + auto *declNode = decl->Node(); + ES2PANDA_ASSERT(declNode->Parent() != nullptr && declNode->Parent()->IsTyped()); + + const checker::Type *expectedObjType = declNode->Parent()->AsTyped()->TsType(); + ES2PANDA_ASSERT(expectedObjType != nullptr && expectedObjType->IsETSObjectType()); + + const auto fullName = etsg->FormClassPropReference(expectedObjType->AsETSObjectType(), propName); etsg->LoadProperty(expr, variableType, objReg, fullName); } etsg->GuardUncheckedType(expr, expr->UncheckedType(), expr->TsType()); diff --git a/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets b/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets new file mode 100644 index 0000000000000000000000000000000000000000..a00400dec82d046278ea07ca396db4188a53b65e --- /dev/null +++ b/ets2panda/test/ast/parser/ets/visit_member_class_null_to_never.ets @@ -0,0 +1,38 @@ +/* + * 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 expr01701 { + val: int; + + static run(): int { + let x: expr01701 | null= null; + let res: int; + try { + res = x!.val; + } catch (error) { + return 0; + } + return 2; + } +} + +function dasgAssert() { + let result = expr01701.run(); + arktest.assertEQ(result, 0); +} + +dasgAssert(); + +/* @@? 23:15 Warning Warning: Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'. */ diff --git a/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets b/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets new file mode 100644 index 0000000000000000000000000000000000000000..a7242bafee34c7be5227c29d2d9cbb4ffb3ff0ad --- /dev/null +++ b/ets2panda/test/ast/parser/ets/visit_member_class_smartcast_never.ets @@ -0,0 +1,26 @@ +/* + * 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. + */ + +final class C { + y: int + readonly x: C|undefined +} + +function f(c: C) { + if (c.x === undefined) { + c.x!.y + } +} +