From 477ad42029eca09cc2ea7fc413c7a23bf9624f66 Mon Sep 17 00:00:00 2001 From: huyunhui Date: Mon, 15 Jan 2024 07:55:26 +0000 Subject: [PATCH 1/5] fix class tdz when class variable is used as lexical variable Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8W8GF Signed-off-by: huyunhui Change-Id: Ic95da9bb7b94118b9417c47b381c60794a9ff4f8 --- es2panda/ir/base/classDefinition.cpp | 42 ++++++++++--------- es2panda/ir/base/methodDefinition.h | 11 +++++ .../test/compiler/js/class-tdz-2-expected.txt | 1 + es2panda/test/compiler/js/class-tdz-2.js | 24 +++++++++++ .../test/compiler/js/class-tdz-3-expected.txt | 1 + es2panda/test/compiler/js/class-tdz-3.js | 22 ++++++++++ 6 files changed, 82 insertions(+), 19 deletions(-) create mode 100644 es2panda/test/compiler/js/class-tdz-2-expected.txt create mode 100644 es2panda/test/compiler/js/class-tdz-2.js create mode 100644 es2panda/test/compiler/js/class-tdz-3-expected.txt create mode 100644 es2panda/test/compiler/js/class-tdz-3.js diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index 67d36bfe0b..a889c6f6ea 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -288,11 +288,7 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti continue; } - if (prop->IsPrivate()) { - continue; - } - - if (prop->IsAbstract()) { + if (prop->IsPrivate() || prop->IsAbstract()) { continue; } @@ -301,7 +297,8 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti switch (prop->Kind()) { case ir::MethodDefinitionKind::METHOD: { - compiler::Operand key = pg->ToPropertyKey(prop->Key(), prop->Computed()); + compiler::Operand key = prop->Computed() ? prop->KeyReg() : + pg->ToPropertyKey(prop->Key(), false); pg->LoadAccumulator(this, dest); const ir::FunctionExpression *func = prop->Value()->AsFunctionExpression(); @@ -312,7 +309,8 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti } case ir::MethodDefinitionKind::GET: case ir::MethodDefinitionKind::SET: { - compiler::VReg keyReg = pg->LoadPropertyKey(prop->Key(), prop->Computed()); + compiler::VReg keyReg = prop->Computed() ? prop->KeyReg() : + pg->LoadPropertyKey(prop->Key(), false); compiler::VReg undef = pg->AllocReg(); pg->LoadConst(this, compiler::Constant::JS_UNDEFINED); @@ -385,6 +383,15 @@ void ClassDefinition::CompileComputedKeys(compiler::PandaGen *pg) const pg->ToComputedPropertyKey(prop->Key()); pg->StoreLexicalVar(prop->Key(), 0, GetSlot(prop->Key())); } + } else if (stmt->IsMethodDefinition()) { + auto *methodDef = stmt->AsMethodDefinition(); + if (methodDef->Computed()) { + compiler::VReg keyReg = pg->AllocReg(); + methodDef->SetKeyReg(keyReg); + methodDef->Key()->Compile(pg); + pg->ToComputedPropertyKey(methodDef->Key()); + pg->StoreAccumulator(methodDef->Key(), keyReg); + } } } } @@ -409,6 +416,10 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const util::StringView ctorId = ctor_->Function()->Scope()->InternalName(); util::BitSet compiled(body_.size()); + if (hasComputedKey_) { + CompileComputedKeys(pg); + } + int32_t bufIdx = CreateClassPublicBuffer(pg, compiled); pg->DefineClassWithBuffer(this, ctorId, bufIdx, baseReg); @@ -422,10 +433,6 @@ void ClassDefinition::Compile(compiler::PandaGen *pg) const CompileMissingProperties(pg, compiled, classReg); - if (hasComputedKey_) { - CompileComputedKeys(pg); - } - if (hasPrivateElement_) { int32_t bufIdx = CreateClassPrivateBuffer(pg); pg->CreatePrivateProperty(this, scope_->privateFieldCnt_, bufIdx); @@ -492,6 +499,8 @@ void ClassDefinition::BuildClassEnvironment(bool useDefineSemantic) if (methodDef->IsPrivate()) { privateProperties.push_back(stmt); methodDef->IsStatic() ? staticPrivateMethodCnt ++ : instancePrivateMethodCnt++; + } else if (methodDef->Computed()) { + hasComputedKey_ = true; } continue; } @@ -503,22 +512,17 @@ void ClassDefinition::BuildClassEnvironment(bool useDefineSemantic) ASSERT(stmt->IsClassProperty()); const auto *prop = stmt->AsClassProperty(); - // Do not process non-static public fields when not using define semantic. if (!prop->IsPrivate() && !prop->IsStatic() && !useDefineSemantic) { continue; } + prop->IsStatic() ? needStaticInitializer_ = true : needInstanceInitializer_ = true; + if (prop->IsComputed() && prop->NeedCompileKey()) { hasComputedKey_ = true; scope_->AddClassVariable(prop->Key()); - } - if (prop->IsStatic()) { - needStaticInitializer_ = true; - } else { - needInstanceInitializer_ = true; - } - if (prop->Key()->IsPrivateIdentifier()) { + } else if (prop->IsPrivate()) { privateFieldCnt++; privateProperties.push_back(stmt); } diff --git a/es2panda/ir/base/methodDefinition.h b/es2panda/ir/base/methodDefinition.h index 217d886302..d5f9ce9085 100644 --- a/es2panda/ir/base/methodDefinition.h +++ b/es2panda/ir/base/methodDefinition.h @@ -151,6 +151,16 @@ public: overloads_.push_back(overload); } + void SetKeyReg(compiler::VReg keyReg) + { + keyReg_ = keyReg; + } + + compiler::VReg KeyReg() const + { + return keyReg_; + } + const ScriptFunction *Function() const; ScriptFunction *Function(); @@ -164,6 +174,7 @@ public: private: MethodDefinitionKind kind_; Expression *key_; + compiler::VReg keyReg_ {0}; FunctionExpression *value_; ModifierFlags modifiers_; ArenaVector overloads_; diff --git a/es2panda/test/compiler/js/class-tdz-2-expected.txt b/es2panda/test/compiler/js/class-tdz-2-expected.txt new file mode 100644 index 0000000000..499d2f8dc4 --- /dev/null +++ b/es2panda/test/compiler/js/class-tdz-2-expected.txt @@ -0,0 +1 @@ +ReferenceError diff --git a/es2panda/test/compiler/js/class-tdz-2.js b/es2panda/test/compiler/js/class-tdz-2.js new file mode 100644 index 0000000000..b687ce41d8 --- /dev/null +++ b/es2panda/test/compiler/js/class-tdz-2.js @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 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. + */ + +try { + class A { + [A]() { + A; + }; + } +} catch (e) { + print(e.name); +} \ No newline at end of file diff --git a/es2panda/test/compiler/js/class-tdz-3-expected.txt b/es2panda/test/compiler/js/class-tdz-3-expected.txt new file mode 100644 index 0000000000..499d2f8dc4 --- /dev/null +++ b/es2panda/test/compiler/js/class-tdz-3-expected.txt @@ -0,0 +1 @@ +ReferenceError diff --git a/es2panda/test/compiler/js/class-tdz-3.js b/es2panda/test/compiler/js/class-tdz-3.js new file mode 100644 index 0000000000..e5f7a04694 --- /dev/null +++ b/es2panda/test/compiler/js/class-tdz-3.js @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 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. + */ + +try { + class A { + [A] = ()=>{A;}; + } +} catch (e) { + print(e.name); +} \ No newline at end of file -- Gitee From e5b9058a7847e37a6aed948fa4ccac406b58f217 Mon Sep 17 00:00:00 2001 From: huyunhui Date: Tue, 16 Jan 2024 07:21:22 +0000 Subject: [PATCH 2/5] Signed-off-by: huyunhui Change-Id: I5029bd6e142c5adcf7e24c669ec7bd106b4b694a --- es2panda/ir/base/classDefinition.cpp | 51 +++++++++++++++------------- es2panda/ir/base/classDefinition.h | 1 + 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/es2panda/ir/base/classDefinition.cpp b/es2panda/ir/base/classDefinition.cpp index a889c6f6ea..040aee4556 100644 --- a/es2panda/ir/base/classDefinition.cpp +++ b/es2panda/ir/base/classDefinition.cpp @@ -309,29 +309,7 @@ void ClassDefinition::CompileMissingProperties(compiler::PandaGen *pg, const uti } case ir::MethodDefinitionKind::GET: case ir::MethodDefinitionKind::SET: { - compiler::VReg keyReg = prop->Computed() ? prop->KeyReg() : - pg->LoadPropertyKey(prop->Key(), false); - - compiler::VReg undef = pg->AllocReg(); - pg->LoadConst(this, compiler::Constant::JS_UNDEFINED); - pg->StoreAccumulator(this, undef); - - compiler::VReg getter = undef; - compiler::VReg setter = undef; - - pg->LoadAccumulator(this, dest); - - compiler::VReg accessor = pg->AllocReg(); - prop->Value()->Compile(pg); - pg->StoreAccumulator(prop->Value(), accessor); - - if (prop->Kind() == ir::MethodDefinitionKind::GET) { - getter = accessor; - } else { - setter = accessor; - } - - pg->DefineGetterSetterByValue(this, dest, keyReg, getter, setter, prop->Computed()); + CompileGetterOrSetter(pg, dest, prop); break; } default: { @@ -626,4 +604,31 @@ void ClassDefinition::CompileSendableClass(compiler::PandaGen *pg) const } } +void ClassDefinition::CompileGetterOrSetter(compiler::PandaGen *pg, compiler::VReg dest, + const MethodDefinition *prop) const +{ + compiler::VReg keyReg = prop->Computed() ? prop->KeyReg() : pg->LoadPropertyKey(prop->Key(), false); + + compiler::VReg undef = pg->AllocReg(); + pg->LoadConst(this, compiler::Constant::JS_UNDEFINED); + pg->StoreAccumulator(this, undef); + + compiler::VReg getter = undef; + compiler::VReg setter = undef; + + pg->LoadAccumulator(this, dest); + + compiler::VReg accessor = pg->AllocReg(); + prop->Value()->Compile(pg); + pg->StoreAccumulator(prop->Value(), accessor); + + if (prop->Kind() == ir::MethodDefinitionKind::GET) { + getter = accessor; + } else { + setter = accessor; + } + + pg->DefineGetterSetterByValue(this, dest, keyReg, getter, setter, prop->Computed()); +} + } // namespace panda::es2panda::ir diff --git a/es2panda/ir/base/classDefinition.h b/es2panda/ir/base/classDefinition.h index 86a584cbb5..5e3f461b12 100644 --- a/es2panda/ir/base/classDefinition.h +++ b/es2panda/ir/base/classDefinition.h @@ -248,6 +248,7 @@ private: void CompileComputedKeys(compiler::PandaGen *pg) const; int32_t CreateFieldTypeBuffer(compiler::PandaGen *pg) const; void CompileSendableClass(compiler::PandaGen *pg) const; + void CompileGetterOrSetter(compiler::PandaGen *pg, compiler::VReg dest, const MethodDefinition *prop) const; binder::ClassScope *scope_; Identifier *ident_; -- Gitee From de16047e1499d7c7e198a364bb73a2e0e37545fe Mon Sep 17 00:00:00 2001 From: dengxinyu Date: Wed, 17 Jan 2024 14:58:38 +0000 Subject: [PATCH 3/5] Description: Bugfix for traverseApiFiles Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/I8X0KV Signed-off-by: dengxinyu Change-Id: Ib88ad85e9e7baeb104e787de10959d7615785dda --- arkguard/src/common/ApiExtractor.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arkguard/src/common/ApiExtractor.ts b/arkguard/src/common/ApiExtractor.ts index 7d9952df7e..310d7435e7 100644 --- a/arkguard/src/common/ApiExtractor.ts +++ b/arkguard/src/common/ApiExtractor.ts @@ -524,6 +524,11 @@ export namespace ApiExtractor { fileNames = fs.readdirSync(apiPath); for (let fileName of fileNames) { let filePath: string = path.join(apiPath, fileName); + try { + fs.accessSync(filePath, fs.constants.R_OK); + } catch (err) { + continue; + } if (fs.statSync(filePath).isDirectory()) { const ohPackageJsonPath = path.join(filePath, 'oh-package.json5'); let packgeNameAndVersion = ''; -- Gitee From 77753206940909d0467a1b9223028327e897ab56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=98=8E=E6=98=9F?= Date: Wed, 17 Jan 2024 07:04:50 +0000 Subject: [PATCH 4/5] =?UTF-8?q?update=20es2panda/BUILD.gn.=20BUILD.gn?= =?UTF-8?q?=E8=A7=84=E8=8C=83=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈明星 --- es2panda/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es2panda/BUILD.gn b/es2panda/BUILD.gn index 04fb8650e5..e937a3e2f5 100644 --- a/es2panda/BUILD.gn +++ b/es2panda/BUILD.gn @@ -398,7 +398,7 @@ ohos_static_library("es2panda_lib") { "${target_out_dir}", "//third_party/icu/icu4c/source/common", "//third_party/icu/icu4c/source/i18n", - "//third_party/icu/icu4c/source ", + "//third_party/icu/icu4c/source", ] deps = [ -- Gitee From aba2d04056f990a3b3f87552a19c36d11b738e0b Mon Sep 17 00:00:00 2001 From: aakmaev Date: Thu, 18 Jan 2024 21:40:20 +0300 Subject: [PATCH 5/5] Code check ets analyzer Signed-off-by: Akmaev Alexey --- ets2panda/checker/ETSAnalyzer.cpp | 141 ++++++++++++++++-------------- ets2panda/checker/ETSAnalyzer.h | 2 + 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 5b7ac5a9ed..7b6f6762dd 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1035,9 +1035,9 @@ checker::ETSObjectType *ChooseCalleeObj(ETSChecker *checker, ir::CallExpression return expr->Callee()->AsMemberExpression()->ObjType(); } -checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, checker::Type *calleeType, - bool isConstructorCall, bool isFunctionalInterface, - bool isUnionTypeWithFunctionalInterface) +checker::Signature *ETSAnalyzer::ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, + checker::Type *calleeType, bool isFunctionalInterface, + bool isUnionTypeWithFunctionalInterface) const { bool extensionFunctionType = expr->Callee()->IsMemberExpression() && checker->ExtensionETSFunctionType(calleeType); @@ -1047,7 +1047,7 @@ checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *ex if (extensionFunctionType) { return ResolveCallExtensionFunction(calleeType->AsETSFunctionType(), checker, expr); } - auto &signatures = ChooseSignatures(checker, calleeType, isConstructorCall, isFunctionalInterface, + auto &signatures = ChooseSignatures(checker, calleeType, expr->IsETSConstructorCall(), isFunctionalInterface, isUnionTypeWithFunctionalInterface); checker::Signature *signature = checker->ResolveCallExpressionAndTrailingLambda(signatures, expr, expr->Start()); if (signature->Function()->IsExtensionMethod()) { @@ -1077,8 +1077,8 @@ checker::Type *ETSAnalyzer::GetReturnType(ir::CallExpression *expr, checker::Typ checker->ThrowTypeError("This expression is not callable.", expr->Start()); } - checker::Signature *signature = ResolveSignature(checker, expr, calleeType, isConstructorCall, - isFunctionalInterface, isUnionTypeWithFunctionalInterface); + checker::Signature *signature = + ResolveSignature(checker, expr, calleeType, isFunctionalInterface, isUnionTypeWithFunctionalInterface); checker->CheckObjectLiteralArguments(signature, expr->Arguments()); checker->AddUndefinedParamsForDefaultParams(signature, expr->Arguments(), checker); @@ -1521,51 +1521,34 @@ checker::Type *ETSAnalyzer::Check(ir::ThisExpression *expr) const return expr->TsType(); } -checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const +void ProcessExclamationMark(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType) { - ETSChecker *checker = GetETSChecker(); - - if (expr->TsType() != nullptr) { - return expr->TsType(); + if (checker->IsNullLikeOrVoidExpression(expr->Argument())) { + auto tsType = checker->CreateETSBooleanType(true); + tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); + expr->SetTsType(tsType); + return; } - auto argType = expr->argument_->Check(checker); - const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; - checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); - auto unboxedOperandType = isCondExpr ? checker->ETSBuiltinTypeAsConditionalType(argType) - : checker->ETSBuiltinTypeAsPrimitiveType(argType); - - if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_MINUS: { - checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); - - // We do not need this const anymore as we are negating the bigint object in runtime - type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); - expr->argument_->SetTsType(type); - expr->SetTsType(type); - return expr->TsType(); - } - default: - // Handled below - // NOTE(kkonsw): handle other unary operators for bigint literals - break; - } + if (operandType == nullptr || !operandType->IsConditionalExprType()) { + checker->ThrowTypeError("Bad operand type, the type of the operand must be boolean type.", + expr->Argument()->Start()); } - if (argType != nullptr && argType->IsETSBigIntType()) { - switch (expr->OperatorType()) { - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_TILDE: { - expr->SetTsType(argType); - return expr->TsType(); - } - default: - break; - } + auto exprRes = operandType->ResolveConditionExpr(); + if (std::get<0>(exprRes)) { + auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); + tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); + expr->SetTsType(tsType); + return; } + expr->SetTsType(checker->GlobalETSBooleanType()); +} + +void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, checker::Type *operandType, + checker::Type *argType) +{ switch (expr->OperatorType()) { case lexer::TokenType::PUNCTUATOR_MINUS: case lexer::TokenType::PUNCTUATOR_PLUS: { @@ -1598,27 +1581,7 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { - if (checker->IsNullLikeOrVoidExpression(expr->Argument())) { - auto tsType = checker->CreateETSBooleanType(true); - tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); - expr->SetTsType(tsType); - break; - } - - if (operandType == nullptr || !operandType->IsConditionalExprType()) { - checker->ThrowTypeError("Bad operand type, the type of the operand must be boolean type.", - expr->Argument()->Start()); - } - - auto exprRes = operandType->ResolveConditionExpr(); - if (std::get<0>(exprRes)) { - auto tsType = checker->CreateETSBooleanType(!std::get<1>(exprRes)); - tsType->AddTypeFlag(checker::TypeFlag::CONSTANT); - expr->SetTsType(tsType); - break; - } - - expr->SetTsType(checker->GlobalETSBooleanType()); + ProcessExclamationMark(checker, expr, operandType); break; } case lexer::TokenType::PUNCTUATOR_DOLLAR_DOLLAR: { @@ -1630,6 +1593,54 @@ checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const break; } } +} + +checker::Type *ETSAnalyzer::Check(ir::UnaryExpression *expr) const +{ + ETSChecker *checker = GetETSChecker(); + + if (expr->TsType() != nullptr) { + return expr->TsType(); + } + + auto argType = expr->argument_->Check(checker); + const auto isCondExpr = expr->OperatorType() == lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK; + checker::Type *operandType = checker->ApplyUnaryOperatorPromotion(argType, true, true, isCondExpr); + auto unboxedOperandType = isCondExpr ? checker->ETSBuiltinTypeAsConditionalType(argType) + : checker->ETSBuiltinTypeAsPrimitiveType(argType); + + if (argType != nullptr && argType->IsETSBigIntType() && argType->HasTypeFlag(checker::TypeFlag::BIGINT_LITERAL)) { + switch (expr->OperatorType()) { + case lexer::TokenType::PUNCTUATOR_MINUS: { + checker::Type *type = checker->CreateETSBigIntLiteralType(argType->AsETSBigIntType()->GetValue()); + + // We do not need this const anymore as we are negating the bigint object in runtime + type->RemoveTypeFlag(checker::TypeFlag::CONSTANT); + expr->argument_->SetTsType(type); + expr->SetTsType(type); + return expr->TsType(); + } + default: + // Handled below + // NOTE(kkonsw): handle other unary operators for bigint literals + break; + } + } + + if (argType != nullptr && argType->IsETSBigIntType()) { + switch (expr->OperatorType()) { + case lexer::TokenType::PUNCTUATOR_MINUS: + case lexer::TokenType::PUNCTUATOR_PLUS: + case lexer::TokenType::PUNCTUATOR_TILDE: { + expr->SetTsType(argType); + return expr->TsType(); + } + default: + break; + } + } + + SetTsTypeForUnaryExpression(checker, expr, operandType, argType); if ((argType != nullptr) && argType->IsETSObjectType() && (unboxedOperandType != nullptr) && unboxedOperandType->HasTypeFlag(checker::TypeFlag::ETS_PRIMITIVE)) { diff --git a/ets2panda/checker/ETSAnalyzer.h b/ets2panda/checker/ETSAnalyzer.h index 074193f35a..9df71aa921 100644 --- a/ets2panda/checker/ETSAnalyzer.h +++ b/ets2panda/checker/ETSAnalyzer.h @@ -40,6 +40,8 @@ public: private: ETSChecker *GetETSChecker() const; void CheckMethodModifiers(ir::MethodDefinition *node) const; + checker::Signature *ResolveSignature(ETSChecker *checker, ir::CallExpression *expr, checker::Type *calleeType, + bool isFunctionalInterface, bool isUnionTypeWithFunctionalInterface) const; checker::Type *GetReturnType(ir::CallExpression *expr, checker::Type *calleeType) const; checker::Type *GetFunctionReturnType(ir::ReturnStatement *st, ir::ScriptFunction *containingFunc) const; }; -- Gitee