From 3fa52a8f657fa32d23c0ab12830159d45a462bc6 Mon Sep 17 00:00:00 2001 From: fcc Date: Fri, 20 Jun 2025 17:20:44 +0800 Subject: [PATCH 001/107] fix instantiate void parameter type After instantiation, parameter type might be 'void'. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICGPYZ Signed-off-by: fcc --- ets2panda/checker/types/signature.cpp | 4 ++++ ets2panda/test/runtime/ets/voidTypeArg.ets | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index 5ced79c411..4533d51d30 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -51,6 +51,10 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub if (newParamType != param->TsType()) { anyChange = true; newParam = param->Copy(allocator, param->Declaration()); + if (newParamType->IsETSVoidType()) { + // since `void` is not allowed to be used as param type + newParamType = checker->GlobalETSUndefinedType(); + } newParam->SetTsType(newParamType); } newSigInfo->params.push_back(newParam); diff --git a/ets2panda/test/runtime/ets/voidTypeArg.ets b/ets2panda/test/runtime/ets/voidTypeArg.ets index 66c7cee2db..e9367a44f6 100644 --- a/ets2panda/test/runtime/ets/voidTypeArg.ets +++ b/ets2panda/test/runtime/ets/voidTypeArg.ets @@ -17,9 +17,17 @@ function foo(a0: T): T { return a0; } +type Fn = (e: T) => void; + +function test(arg: Fn) {} + function main() : void { foo(undefined); let bfoo = foo(undefined); arktest.assertEQ(bfoo, undefined) + + test((e) => { + arktest.assertEQ(e, undefined) + }) } -- Gitee From fdaa77f5a63a676c76a018834a2cf00c8e6086ab Mon Sep 17 00:00:00 2001 From: yaohaosen Date: Tue, 17 Jun 2025 22:02:45 +0800 Subject: [PATCH 002/107] [LSP] Fix getFileSource from emty file Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICFWG0 Signed-off-by: yaohaosen --- ets2panda/bindings/src/lsp_helper.ts | 4 ++-- ets2panda/bindings/test/cases.ts | 4 ++++ .../bindings/test/expected/getFileSource.json | 3 +++ .../testcases/getFileSource/getFileSource1.ets | 16 ++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 ets2panda/bindings/test/expected/getFileSource.json create mode 100644 ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets diff --git a/ets2panda/bindings/src/lsp_helper.ts b/ets2panda/bindings/src/lsp_helper.ts index aba1bcdaaf..c6c47955bd 100644 --- a/ets2panda/bindings/src/lsp_helper.ts +++ b/ets2panda/bindings/src/lsp_helper.ts @@ -137,8 +137,8 @@ export class Lsp { } private getFileSource(filePath: string): string { - const getSource = this.filesMap.get(filePath) || this.getFileContent(filePath); - if (!getSource) { + const getSource = this.filesMap.get(filePath) || this.getFileContent(filePath) || fs.readFileSync(filePath, 'utf8'); + if (getSource === undefined) { throw new Error(`File content not found for path: ${filePath}`); } return getSource.replace(/\r\n/g, '\n'); diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts index 34736cfaf3..8038dbe327 100644 --- a/ets2panda/bindings/test/cases.ts +++ b/ets2panda/bindings/test/cases.ts @@ -62,6 +62,10 @@ export const testCases: TestCases = { expectedFilePath: resolveTestPath('test/expected/getFileReferences.json'), '1': [resolveTestPath('test/testcases/getFileReferences/getFileReferences1_export.ets')] }, + getFileSource: { + expectedFilePath: resolveTestPath('test/expected/getFileSource.json'), + '1': [resolveTestPath('test/testcases/getFileSource/getFileSource1.ets')] + }, getReferencesAtPosition: { expectedFilePath: resolveTestPath('test/expected/getReferencesAtPosition.json'), '1': [resolveTestPath('test/testcases/getReferencesAtPosition/getReferencesAtPosition1.ets'), 613], diff --git a/ets2panda/bindings/test/expected/getFileSource.json b/ets2panda/bindings/test/expected/getFileSource.json new file mode 100644 index 0000000000..e893655add --- /dev/null +++ b/ets2panda/bindings/test/expected/getFileSource.json @@ -0,0 +1,3 @@ +{ + "1": "/*\n * Copyright (c) 2025 Huawei Device Co., Ltd.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nlet a = 1;" +} \ No newline at end of file diff --git a/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets b/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets new file mode 100644 index 0000000000..119751e901 --- /dev/null +++ b/ets2panda/bindings/test/testcases/getFileSource/getFileSource1.ets @@ -0,0 +1,16 @@ +/* + * 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. + */ + +let a = 1; \ No newline at end of file -- Gitee From 0bebc604868785c955a08ae50b2472f4d925c641 Mon Sep 17 00:00:00 2001 From: igorlegalov Date: Fri, 27 Jun 2025 18:19:54 +0300 Subject: [PATCH 003/107] createFromJSONValue extension method Issue: https://gitee.com/open_harmony/dashboard?issue_id=ICGRNK Testing: all pre-merge tests passed Signed-off-by: igorlegalov --- ets2panda/test/ast/parser/ets/keyof_predefined_type.ets | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets index 6700401caf..1f476b40e9 100644 --- a/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets +++ b/ets2panda/test/ast/parser/ets/keyof_predefined_type.ets @@ -18,5 +18,5 @@ function main():void{ let c2:keyof Int = /* @@ label2 */"field1" } -/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"toShort"|"toChar"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"$_hashCode"|"add"|"toByte"|"floatValue"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ -/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"toShort"|"toChar"|"createFromJSONValue"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"$_hashCode"|"add"|"toByte"|"floatValue"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label1 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"$_hashCode"|"add"|"toByte"|"floatValue"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ +/* @@@ label2 Error TypeError: Type '"field1"' cannot be assigned to type '"toDouble"|"toLong"|"byteValue"|"doubleValue"|"longValue"|"equals"|"isGreaterEqualThan"|"intValue"|"toInt"|"div"|"shortValue"|"isLessThan"|"isLessEqualThan"|"mul"|"sub"|"toString"|"toFloat"|"compareTo"|"isGreaterThan"|"unboxed"|"$_hashCode"|"add"|"toByte"|"floatValue"|"toShort"|"toChar"|"valueOf"|"MIN_VALUE"|"MAX_VALUE"|"BIT_SIZE"|"BYTE_SIZE"' */ -- Gitee From 8bd8d2d54af4b47c7961b431f3051da4f33f2fb3 Mon Sep 17 00:00:00 2001 From: wangjiahui Date: Tue, 1 Jul 2025 16:56:52 +0800 Subject: [PATCH 004/107] codecheck fix Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJ6XK Test scenarios:fix codecheck Signed-off-by: wangjiahui --- .../scripts/testRunner/coverage_prepare.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ets2panda/linter/scripts/testRunner/coverage_prepare.js b/ets2panda/linter/scripts/testRunner/coverage_prepare.js index 2a746b4b09..fddbdb8466 100644 --- a/ets2panda/linter/scripts/testRunner/coverage_prepare.js +++ b/ets2panda/linter/scripts/testRunner/coverage_prepare.js @@ -21,19 +21,19 @@ const buildDir = path.join(projectRoot, 'build'); const coverageDir = path.join(projectRoot, 'coverage'); const buildInstrumentDir = path.join(coverageDir, 'build_instrument'); -function copyDirectory(src, dest) { - fs.mkdirSync(dest, { recursive: true }); +function copyDirectory(srcDirectory, destDirectory) { + fs.mkdirSync(destDirectory, { recursive: true }); - const entries = fs.readdirSync(src, { withFileTypes: true }); + const directoryEntries = fs.readdirSync(srcDirectory, { withFileTypes: true }); - for (const entry of entries) { - const srcPath = path.join(src, entry.name); - const destPath = path.join(dest, entry.name); + for (const dirent of directoryEntries) { + const srcFilepath = path.join(srcDirectory, dirent.name); + const destFilepath = path.join(destDirectory, dirent.name); - if (entry.isDirectory()) { - copyDirectory(srcPath, destPath); + if (dirent.isDirectory()) { + copyDirectory(srcFilepath, destFilepath); } else { - fs.copyFileSync(srcPath, destPath); + fs.copyFileSync(srcFilepath, destFilepath); } } } -- Gitee From f1624913a14d14167f0a17938a556f4a99412df5 Mon Sep 17 00:00:00 2001 From: nikozer Date: Mon, 30 Jun 2025 22:13:31 +0300 Subject: [PATCH 005/107] codecheck fixes Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIYVO Test: ninja tests Signed-off-by: nikozer --- .../lowering/ets/localClassLowering.cpp | 3 +++ .../lowering/ets/objectIndexAccess.cpp | 1 + .../compiler/lowering/ets/objectIterator.cpp | 2 ++ .../lowering/ets/objectLiteralLowering.cpp | 25 ++++++++++++------- .../ets/optionalArgumentsLowering.cpp | 1 + .../lowering/ets/optionalLowering.cpp | 1 + .../compiler/lowering/ets/recordLowering.cpp | 1 + .../lowering/ets/resizableArrayLowering.cpp | 1 + .../lowering/ets/restArgsLowering.cpp | 5 +++- .../lowering/ets/restTupleLowering.cpp | 4 +++ .../compiler/lowering/ets/spreadLowering.cpp | 7 +++++- .../lowering/ets/stringComparison.cpp | 1 + .../lowering/ets/stringConstantsLowering.cpp | 1 + .../ets/stringConstructorLowering.cpp | 1 + .../ets/topLevelStmts/globalClassHandler.cpp | 13 +++++++--- .../topLevelStmts/globalDeclTransformer.cpp | 3 +++ .../ets/topLevelStmts/importExportDecls.cpp | 1 + .../ets/topLevelStmts/importExportDecls.h | 2 +- .../compiler/lowering/ets/unionLowering.cpp | 9 ++++--- ets2panda/ir/statements/annotationUsage.cpp | 2 ++ ets2panda/ir/statements/blockStatement.cpp | 1 + ets2panda/ir/statements/breakStatement.cpp | 1 + ets2panda/ir/statements/continueStatement.cpp | 1 + ets2panda/ir/statements/forOfStatement.cpp | 1 + ets2panda/ir/statements/tryStatement.cpp | 17 +++++++++++-- .../ir/statements/variableDeclaration.cpp | 5 +++- .../ir/statements/variableDeclarator.cpp | 1 + ets2panda/parser/TSparser.cpp | 3 +++ ets2panda/parser/TypedParser.cpp | 19 +++++++++++--- ets2panda/parser/expressionParser.cpp | 1 + ets2panda/varbinder/scope.h | 4 ++- ets2panda/varbinder/varbinder.cpp | 9 ++++--- ets2panda/varbinder/variable.cpp | 5 ++-- 33 files changed, 122 insertions(+), 30 deletions(-) diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.cpp b/ets2panda/compiler/lowering/ets/localClassLowering.cpp index 439208e640..5096f8bac4 100644 --- a/ets2panda/compiler/lowering/ets/localClassLowering.cpp +++ b/ets2panda/compiler/lowering/ets/localClassLowering.cpp @@ -52,6 +52,7 @@ static ir::ClassProperty *CreateCapturedField(public_lib::Context *ctx, const va var->SetTsType(capturedVar->TsType()); fieldIdent->SetVariable(var); + ES2PANDA_ASSERT(field != nullptr); field->SetTsType(capturedVar->TsType()); decl->BindNode(field); return field; @@ -91,6 +92,7 @@ void LocalClassConstructionPhase::CreateClassPropertiesForCapturedVariables( LOG(DEBUG, ES2PANDA) << " - Creating property (" << property->Id()->Name() << ") for captured variable: " << var->Name(); properties.push_back(property); + ES2PANDA_ASSERT(property->Id() != nullptr); variableMap[var] = property->Id()->Variable(); propertyMap[var] = property; idx++; @@ -199,6 +201,7 @@ void LocalClassConstructionPhase::RemapReferencesFromCapturedVariablesToClassPro if (it->IsMethodDefinition() && !it->AsMethodDefinition()->IsConstructor()) { LOG(DEBUG, ES2PANDA) << " - Rebinding variable rerferences in: " << it->AsMethodDefinition()->Id()->Name().Mutf8().c_str(); + ES2PANDA_ASSERT(it->AsMethodDefinition()->Function() != nullptr); if (it->AsMethodDefinition()->Function()->Body() == nullptr && it->AsMethodDefinition()->AsyncPairMethod() != nullptr) { it->AsMethodDefinition()->AsyncPairMethod()->Function()->Body()->IterateRecursively( diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index 8382b1dd2c..9fcd05a2db 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -71,6 +71,7 @@ ir::Expression *ObjectIndexLowering::ProcessIndexSetAccess(parser::ETSParser *pa memberExpression->Property(), assignmentExpression->Right()); setter = loweringResult; } + ES2PANDA_ASSERT(loweringResult != nullptr); loweringResult->SetParent(assignmentExpression->Parent()); loweringResult->SetRange(assignmentExpression->Range()); setter->AddModifier(ir::ModifierFlags::ARRAY_SETTER); diff --git a/ets2panda/compiler/lowering/ets/objectIterator.cpp b/ets2panda/compiler/lowering/ets/objectIterator.cpp index c3136f256e..a067befa5b 100644 --- a/ets2panda/compiler/lowering/ets/objectIterator.cpp +++ b/ets2panda/compiler/lowering/ets/objectIterator.cpp @@ -108,6 +108,7 @@ static ir::OpaqueTypeNode *FindIterValueType(checker::ETSObjectType *type, Arena checker::PropertySearchFlags::SEARCH_INSTANCE_METHOD | checker::PropertySearchFlags::SEARCH_IN_INTERFACES | checker::PropertySearchFlags::SEARCH_IN_BASE); + ES2PANDA_ASSERT(itor != nullptr); auto const &sigs = itor->TsType()->AsETSFunctionType()->CallSignatures(); checker::ETSObjectType *itorReturnType = nullptr; for (auto &sig : sigs) { @@ -170,6 +171,7 @@ ir::Statement *ObjectIteratorLowering::ProcessObjectIterator(public_lib::Context auto *const loweringResult = parser->CreateFormattedStatement( whileStatement, iterIdent, forOfStatement->Right(), nextIdent, iterIdent->Clone(allocator, nullptr), nextIdent->Clone(allocator, nullptr), loopVariableIdent, nextIdent->Clone(allocator, nullptr), typeNode); + ES2PANDA_ASSERT(loweringResult != nullptr); loweringResult->SetParent(forOfStatement->Parent()); loweringResult->SetRange(forOfStatement->Range()); diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index 8e0fbcfb05..29117a736e 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -100,6 +100,7 @@ static void AllowRequiredTypeInstantiation(const ir::Expression *const loweringR static bool CheckReadonlyAndUpdateCtorArgs(const ir::Identifier *key, ir::Expression *value, std::map &ctorArgumentsMap) { + ES2PANDA_ASSERT(key != nullptr); auto varType = (key->Variable() != nullptr) ? key->Variable()->TsType() : nullptr; if (varType == nullptr || varType->HasTypeFlag(checker::TypeFlag::SETTER)) { return false; @@ -162,6 +163,18 @@ static void SetInstanceArguments(ArenaVector &statements, Arena instance->SetArguments(std::move(ctorArguments)); } +static void GenerateArgsForAnonymousClassType(const checker::ETSObjectType *classType, const bool &isAnonymous, + std::map &ctorArgumentsMap) +{ + if (isAnonymous) { + checker::Signature *sig = classType->ConstructSignatures().front(); + for (auto param : sig->Params()) { + ES2PANDA_ASSERT(param->Declaration() != nullptr); + ctorArgumentsMap.emplace(param->Declaration()->Name(), nullptr); + } + } +} + static void GenerateNewStatements(public_lib::Context *ctx, ir::ObjectExpression *objExpr, std::stringstream &ss, std::vector &newStmts, std::deque &nestedBlckExprs, @@ -186,13 +199,7 @@ static void GenerateNewStatements(public_lib::Context *ctx, ir::ObjectExpression bool isAnonymous = IsAnonymousClassType(classType); std::map ctorArgumentsMap; - if (isAnonymous) { - checker::Signature *sig = classType->ConstructSignatures().front(); - for (auto param : sig->Params()) { - ES2PANDA_ASSERT(param->Declaration() != nullptr); - ctorArgumentsMap.emplace(param->Declaration()->Name(), nullptr); - } - } + GenerateArgsForAnonymousClassType(classType, isAnonymous, ctorArgumentsMap); for (auto *propExpr : objExpr->Properties()) { // Skip possibly invalid properties: @@ -218,7 +225,7 @@ static void GenerateNewStatements(public_lib::Context *ctx, ir::ObjectExpression if (isAnonymous && CheckReadonlyAndUpdateCtorArgs(keyIdent, value, ctorArgumentsMap)) { continue; } - + ES2PANDA_ASSERT(genSymIdent != nullptr); ss << "@@I" << addNode(genSymIdent->Clone(allocator, nullptr)) << ".@@I" << addNode(keyIdent); if (value->IsBlockExpression()) { @@ -269,7 +276,7 @@ static ir::AstNode *HandleObjectLiteralLowering(public_lib::Context *ctx, ir::Ob GenerateNewStatements(ctx, objExpr, ss, newStmts, nestedBlckExprs, ctorArguments); auto *loweringResult = parser->CreateFormattedExpression(ss.str(), newStmts); - + ES2PANDA_ASSERT(loweringResult != nullptr); SetInstanceArguments(loweringResult->AsBlockExpression()->Statements(), ctorArguments); loweringResult->SetParent(objExpr->Parent()); diff --git a/ets2panda/compiler/lowering/ets/optionalArgumentsLowering.cpp b/ets2panda/compiler/lowering/ets/optionalArgumentsLowering.cpp index 5c2892b8c9..c58a3b93f3 100644 --- a/ets2panda/compiler/lowering/ets/optionalArgumentsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/optionalArgumentsLowering.cpp @@ -52,6 +52,7 @@ static void TransformArguments(public_lib::Context *ctx, ir::Expression *callLik size_t missing = signature->ArgCount() - arguments.size(); for (size_t i = 0; i < missing; ++i) { auto undefArg = allocator->New(); + ES2PANDA_ASSERT(undefArg != nullptr); undefArg->SetTsType(checker->GlobalETSUndefinedType()); arguments.push_back(undefArg); undefArg->SetParent(callLike); diff --git a/ets2panda/compiler/lowering/ets/optionalLowering.cpp b/ets2panda/compiler/lowering/ets/optionalLowering.cpp index 36f6aefe14..73c5b83e85 100644 --- a/ets2panda/compiler/lowering/ets/optionalLowering.cpp +++ b/ets2panda/compiler/lowering/ets/optionalLowering.cpp @@ -39,6 +39,7 @@ static ir::AstNode *LowerOptionalExpr(GetSource const &getSource, SetSource cons auto expressionCtx = varbinder::LexicalScope::Enter(varbinder, NearestScope(expr)); auto *tmpIdent = Gensym(allocator); + ES2PANDA_ASSERT(tmpIdent != nullptr); auto *tmpIdentClone = tmpIdent->Clone(allocator, nullptr); // '0's act as placeholders diff --git a/ets2panda/compiler/lowering/ets/recordLowering.cpp b/ets2panda/compiler/lowering/ets/recordLowering.cpp index 889c864962..830a727dd5 100644 --- a/ets2panda/compiler/lowering/ets/recordLowering.cpp +++ b/ets2panda/compiler/lowering/ets/recordLowering.cpp @@ -224,6 +224,7 @@ ir::Expression *RecordLowering::UpdateObjectExpression(ir::ObjectExpression *exp // Create Block Expression auto block = CreateBlockExpression(expr, typeArguments[0], typeArguments[1], ctx); + ES2PANDA_ASSERT(block != nullptr); block->SetParent(expr->Parent()); // Run checks diff --git a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp index 2b9012963b..5da6f69149 100644 --- a/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp +++ b/ets2panda/compiler/lowering/ets/resizableArrayLowering.cpp @@ -27,6 +27,7 @@ static ir::AstNode *ConvertToResizableArrayType(ir::TSArrayType *node, public_li auto *parser = ctx->parser->AsETSParser(); ir::TypeNode *typeAnnotation = parser->CreateFormattedTypeAnnotation((insideAnnotdecl ? "FixedArray<" : "Array<") + node->ElementType()->DumpEtsSrc() + ">"); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetAnnotations(node->Annotations()); typeAnnotation->SetParent(node->Parent()); typeAnnotation->SetRange(node->Range()); diff --git a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp index 9fe4183e9b..952da6e17e 100644 --- a/ets2panda/compiler/lowering/ets/restArgsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restArgsLowering.cpp @@ -51,6 +51,7 @@ static ir::BlockExpression *CreateRestArgsBlockExpression(public_lib::Context *c args.emplace_back(argumentSymbol->Clone(allocator, nullptr)); ss << "@@I3[@@I4] = @@I5;"; args.emplace_back(arraySymbol->Clone(allocator, nullptr)); + ES2PANDA_ASSERT(iteratorIndex != nullptr); args.emplace_back(iteratorIndex->Clone(allocator, nullptr)); args.emplace_back(iteratorSymbol->Clone(allocator, nullptr)); ss << "@@I6 = @@I7 + 1;"; @@ -69,6 +70,7 @@ static ir::BlockExpression *ConvertSpreadToBlockExpression(public_lib::Context * ir::SpreadElement *spreadElement) { auto *blockExpression = CreateRestArgsBlockExpression(context, spreadElement); + ES2PANDA_ASSERT(blockExpression != nullptr); blockExpression->SetParent(spreadElement->Parent()); blockExpression->SetRange(spreadElement->Range()); @@ -119,6 +121,7 @@ static ir::Expression *CreateRestArgsArray(public_lib::Context *context, ArenaVe ss << "for (let i = 0; i < @@I8.length; ++i) { @@I9[i] = @@I10[i]}"; ss << "@@I11;"; auto *arrayExpr = checker->AllocNode(std::move(copiedArguments), allocator); + ES2PANDA_ASSERT(type != nullptr); auto *loweringResult = parser->CreateFormattedExpression( ss.str(), genSymIdent, type->Clone(allocator, nullptr), arrayExpr, genSymIdent2, type, type->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), genSymIdent->Clone(allocator, nullptr), @@ -142,7 +145,7 @@ static ir::CallExpression *RebuildCallExpression(public_lib::Context *context, i auto *newCall = util::NodeAllocator::ForceSetParent(allocator, originalCall->Callee(), std::move(newArgs), nullptr, false); - + ES2PANDA_ASSERT(newCall != nullptr); restArgsArray->SetParent(newCall); newCall->SetParent(originalCall->Parent()); newCall->AddModifier(originalCall->Modifiers()); diff --git a/ets2panda/compiler/lowering/ets/restTupleLowering.cpp b/ets2panda/compiler/lowering/ets/restTupleLowering.cpp index c01e578292..14aff4b616 100644 --- a/ets2panda/compiler/lowering/ets/restTupleLowering.cpp +++ b/ets2panda/compiler/lowering/ets/restTupleLowering.cpp @@ -209,6 +209,7 @@ ir::ArrayExpression *CreateArrayExpression(public_lib::Context *ctx, const Arena ArenaVector elements(ctx->Allocator()->Adapter()); auto *arrayExpr = ctx->AllocNode(std::move(elementsInit), ctx->Allocator()); + ES2PANDA_ASSERT(arrayExpr != nullptr); for (auto tupleElementAnno : newRestParams) { auto &tupleElementName = tupleElementAnno->AsETSParameterExpression()->Ident()->AsIdentifier()->Name(); ir::Expression *arg = ctx->AllocNode(tupleElementName, allocator); @@ -262,6 +263,7 @@ ir::ScriptFunction *CreateNewScriptFunction(public_lib::Context *ctx, ir::Script allocator, ir::ScriptFunction::ScriptFunctionData { body, ir::FunctionSignature(newParamDeclaration, std::move(newParams), newReturnTypeAnno), scriptFunc->Flags() | ir::ScriptFunctionFlags::SYNTHETIC}); + ES2PANDA_ASSERT(newScriptFunc != nullptr); newScriptFunc->AddModifier(scriptFunc->AsScriptFunction()->Modifiers()); ArenaVector annotationUsages {allocator->Adapter()}; @@ -283,6 +285,7 @@ ir::VariableDeclaration *CreateNewVariableDeclaration(public_lib::Context *ctx, util::StringView tupleIdentName = restParam->Ident()->Name(); auto *newId = ctx->AllocNode(tupleIdentName, allocator); + ES2PANDA_ASSERT(newId != nullptr); ir::TypeNode *typeAnnotation = restParam->TypeAnnotation()->Clone(allocator, newId); newId->SetTsTypeAnnotation(typeAnnotation); newTuple->SetParent(typeAnnotation); @@ -321,6 +324,7 @@ ir::MethodDefinition *CreateNewMethodDefinition(public_lib::Context *ctx, ir::Me auto *const methodDef = ctx->AllocNode(definition->AsMethodDefinition()->Kind(), methodKey, function, definition->AsMethodDefinition()->Modifiers(), allocator, false); + ES2PANDA_ASSERT(methodDef != nullptr); methodDef->SetParent(definition->Parent()); return methodDef; diff --git a/ets2panda/compiler/lowering/ets/spreadLowering.cpp b/ets2panda/compiler/lowering/ets/spreadLowering.cpp index bf6b4e6c2e..416e61cd70 100644 --- a/ets2panda/compiler/lowering/ets/spreadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/spreadLowering.cpp @@ -58,6 +58,7 @@ ir::Identifier *CreateNewArrayLengthStatement(public_lib::Context *ctx, ir::Arra auto *const allocator = ctx->allocator; auto *const parser = ctx->parser->AsETSParser(); ir::Identifier *newArrayLengthId = Gensym(allocator); + ES2PANDA_ASSERT(newArrayLengthId != nullptr); std::vector nodesWaitingInsert {newArrayLengthId->Clone(allocator, nullptr)}; size_t argumentCount = 1; std::stringstream lengthString; @@ -108,6 +109,7 @@ static ir::Identifier *CreateNewArrayDeclareStatement(public_lib::Context *ctx, newArrayDeclareStr << "let @@I1: FixedArray<@@T2> = new (@@T3)[@@I4];" << std::endl; } + ES2PANDA_ASSERT(newArrayLengthId != nullptr); ir::Statement *newArrayDeclareSt = parser->CreateFormattedStatement( newArrayDeclareStr.str(), newArrayId->Clone(allocator, nullptr), arrayElementType, arrayElementType, newArrayLengthId->Clone(allocator, nullptr)); @@ -167,6 +169,7 @@ static ir::Identifier *CreateNewTupleDeclareStatement(public_lib::Context *ctx, auto *const allocator = ctx->allocator; auto *const parser = ctx->parser->AsETSParser(); ir::Identifier *newTupleId = Gensym(allocator); + ES2PANDA_ASSERT(newTupleId != nullptr); checker::ETSTupleType *tupleType = array->TsType()->AsETSTupleType(); std::stringstream newArrayDeclareStr; @@ -197,6 +200,7 @@ static ir::Statement *CreateElementsAssignStatementBySpreadArr(public_lib::Conte elementsAssignStr << "@@I7++;"; elementsAssignStr << "}"; + ES2PANDA_ASSERT(spreadArrIterator != nullptr); ir::Statement *elementsAssignStatement = parser->CreateFormattedStatement( elementsAssignStr.str(), spreadArrIterator->Clone(allocator, nullptr), spId->Clone(allocator, nullptr), newArrayId->Clone(allocator, nullptr), newArrayIndexId->Clone(allocator, nullptr), @@ -329,6 +333,7 @@ static ir::BlockExpression *CreateLoweredExpressionForArray(public_lib::Context ir::Identifier *newArrayLengthId = CreateNewArrayLengthStatement(ctx, array, spreadArrayIds, statements); ir::Identifier *newArrayId = CreateNewArrayDeclareStatement(ctx, array, statements, newArrayLengthId); + ES2PANDA_ASSERT(newArrayId != nullptr); ir::Identifier *newArrayIndexId = Gensym(allocator); statements.emplace_back( parser->CreateFormattedStatement("let @@I1 = 0", newArrayIndexId->Clone(allocator, nullptr))); @@ -351,7 +356,7 @@ static ir::BlockExpression *CreateLoweredExpressionForTuple(public_lib::Context ArenaVector statements(allocator->Adapter()); ir::Identifier *newTupleId = CreateNewTupleDeclareStatement(ctx, array, statements); - + ES2PANDA_ASSERT(newTupleId != nullptr); statements.emplace_back(parser->CreateFormattedStatement("@@I1;", newTupleId->Clone(allocator, nullptr))); return checker->AllocNode(std::move(statements)); } diff --git a/ets2panda/compiler/lowering/ets/stringComparison.cpp b/ets2panda/compiler/lowering/ets/stringComparison.cpp index 056f7b216c..e25361a710 100644 --- a/ets2panda/compiler/lowering/ets/stringComparison.cpp +++ b/ets2panda/compiler/lowering/ets/stringComparison.cpp @@ -83,6 +83,7 @@ void StringComparisonLowering::ProcessBinaryExpression(ir::BinaryExpression *exp ir::Expression *accessor = nullptr; auto *zeroExpr = checker->AllocNode(lexer::Number(int32_t(0))); auto *const callee = checker->AllocNode("compareTo", checker->Allocator()); + ES2PANDA_ASSERT(callee != nullptr); auto *var = checker->GlobalBuiltinETSStringType()->GetProperty(callee->AsIdentifier()->Name(), checker::PropertySearchFlags::SEARCH_METHOD); callee->SetVariable(var); diff --git a/ets2panda/compiler/lowering/ets/stringConstantsLowering.cpp b/ets2panda/compiler/lowering/ets/stringConstantsLowering.cpp index 8f255cb457..9484a99138 100644 --- a/ets2panda/compiler/lowering/ets/stringConstantsLowering.cpp +++ b/ets2panda/compiler/lowering/ets/stringConstantsLowering.cpp @@ -30,6 +30,7 @@ static ir::AstNode *FoldConcat(public_lib::Context *ctx, ir::BinaryExpression *c auto const resStr = util::UString(lhs->Str().Mutf8() + rhs->Str().Mutf8(), ctx->allocator).View(); auto resNode = util::NodeAllocator::Alloc(ctx->allocator, resStr); + ES2PANDA_ASSERT(resNode != nullptr); resNode->SetParent(concat->Parent()); resNode->SetRange({lhs->Range().start, rhs->Range().end}); return resNode; diff --git a/ets2panda/compiler/lowering/ets/stringConstructorLowering.cpp b/ets2panda/compiler/lowering/ets/stringConstructorLowering.cpp index 244957d3a4..19429df0d3 100644 --- a/ets2panda/compiler/lowering/ets/stringConstructorLowering.cpp +++ b/ets2panda/compiler/lowering/ets/stringConstructorLowering.cpp @@ -72,6 +72,7 @@ ir::Expression *ReplaceStringConstructor(public_lib::Context *const ctx, if (argType->IsETSNullType() || argType->IsETSUndefinedType()) { auto *literal = argType->IsETSNullType() ? ctx->AllocNode("null") : ctx->AllocNode("undefined"); + ES2PANDA_ASSERT(literal != nullptr); literal->SetParent(newClassInstExpr->Parent()); // Run checker diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 0f40ccf538..77adc2ac37 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -164,6 +164,7 @@ ir::ClassDeclaration *GlobalClassHandler::CreateTransformedClass(ir::ETSModule * auto *classDef = NodeAllocator::Alloc( allocator_, allocator_, ident, ir::ClassDefinitionModifiers::CLASS_DECL, ir::ModifierFlags::ABSTRACT, Language(Language::Id::ETS)); + ES2PANDA_ASSERT(classDef != nullptr); classDef->SetRange(ns->Range()); classDef->AddModifier(ns->Modifiers()); auto *classDecl = NodeAllocator::Alloc(allocator_, classDef, allocator_); @@ -181,6 +182,7 @@ ir::ClassDeclaration *GlobalClassHandler::CreateTransformedClass(ir::ETSModule * static void InsertInGlobal(ir::ClassDefinition *globalClass, ir::AstNode *node) { + ES2PANDA_ASSERT(node != nullptr); globalClass->BodyForUpdate().insert(globalClass->Body().begin(), node); node->SetParent(globalClass); } @@ -221,6 +223,7 @@ void GlobalClassHandler::SetupGlobalMethods(ArenaVector &&initS ir::MethodDefinition *initMethod = CreateGlobalMethod(compiler::Signatures::INIT_METHOD, std::move(initStatements)); InsertInGlobal(globalClass, initMethod); + ES2PANDA_ASSERT(initMethod->Function()); if (!initMethod->Function()->Body()->AsBlockStatement()->Statements().empty()) { AddInitCallToStaticBlock(globalClass, initMethod); } @@ -282,6 +285,7 @@ void GlobalClassHandler::TransformBrokenNamespace(ir::AstNode *node) ir::ClassDeclaration *GlobalClassHandler::TransformNamespace(ir::ETSModule *ns) { ir::ClassDeclaration *const globalDecl = CreateTransformedClass(ns); + ES2PANDA_ASSERT(globalDecl != nullptr); ir::ClassDefinition *const globalClass = globalDecl->Definition(); ArenaVector immediateInitializers(allocator_->Adapter()); @@ -366,6 +370,7 @@ void GlobalClassHandler::SetupGlobalClass(const ArenaVector & ArenaUnorderedSet packageInitializerBlockCount(allocator_->Adapter()); ir::ClassDeclaration *const globalDecl = CreateGlobalClass(globalProgram_); + ES2PANDA_ASSERT(globalDecl != nullptr); ir::ClassDefinition *const globalClass = globalDecl->Definition(); // NOTE(vpukhov): a clash inside program list is possible @@ -429,7 +434,7 @@ ir::MethodDefinition *GlobalClassHandler::CreateGlobalMethod(const std::string_v allocator_, allocator_, ir::ScriptFunction::ScriptFunctionData { body, std::move(funcSignature), functionFlags, {}, Language(Language::Id::ETS)}); - + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(ident); func->AddModifier(functionModifiers); @@ -469,7 +474,7 @@ void GlobalClassHandler::AddInitializerBlockToStaticBlock(ir::ClassDefinition *g auto *staticBlock = (*maybeStaticBlock)->AsClassStaticBlock(); auto *initializerStmts = NodeAllocator::ForceSetParent(allocator_, allocator_, std::move(initializerBlocks)); - + ES2PANDA_ASSERT(initializerStmts != nullptr); auto *blockBody = staticBlock->Function()->Body()->AsBlockStatement(); initializerStmts->SetParent(blockBody); blockBody->AddStatement(initializerStmts); @@ -485,6 +490,7 @@ void GlobalClassHandler::AddInitCallToStaticBlock(ir::ClassDefinition *globalCla ES2PANDA_ASSERT(maybeStaticBlock != globalBody.end()); auto *staticBlock = (*maybeStaticBlock)->AsClassStaticBlock(); + ES2PANDA_ASSERT(initMethod->Id() != nullptr); auto *callee = RefIdent(initMethod->Id()->Name()); auto *const callExpr = NodeAllocator::Alloc( @@ -587,7 +593,7 @@ ir::ClassStaticBlock *GlobalClassHandler::CreateStaticBlock(ir::ClassDefinition ir::ScriptFunction::ScriptFunctionData {body, ir::FunctionSignature(nullptr, std::move(params), nullptr), ir::ScriptFunctionFlags::STATIC_BLOCK | ir::ScriptFunctionFlags::HIDDEN, ir::ModifierFlags::STATIC, Language(Language::Id::ETS)}); - + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); auto *funcExpr = NodeAllocator::Alloc(allocator_, func); @@ -646,6 +652,7 @@ ir::ClassDeclaration *GlobalClassHandler::CreateGlobalClass(const parser::Progra auto *classDef = NodeAllocator::Alloc(allocator_, allocator_, ident, ir::ClassDefinitionModifiers::GLOBAL, ir::ModifierFlags::ABSTRACT, Language(Language::Id::ETS)); + ES2PANDA_ASSERT(classDef != nullptr); classDef->SetRange(rangeToStartOfFile); auto *classDecl = NodeAllocator::Alloc(allocator_, classDef, allocator_); classDecl->SetRange(rangeToStartOfFile); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp index 4c4576fa1b..a5abdb80a0 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalDeclTransformer.cpp @@ -56,6 +56,7 @@ void GlobalDeclTransformer::VisitOverloadDeclaration(ir::OverloadDeclaration *ov void GlobalDeclTransformer::VisitFunctionDeclaration(ir::FunctionDeclaration *funcDecl) { auto *funcExpr = util::NodeAllocator::ForceSetParent(allocator_, funcDecl->Function()); + ES2PANDA_ASSERT(funcExpr != nullptr); funcDecl->Function()->SetStart(funcDecl->Function()->Id()->Start()); funcExpr->SetRange(funcDecl->Function()->Range()); ir::MethodDefinitionKind methodKind; @@ -102,6 +103,7 @@ void GlobalDeclTransformer::VisitVariableDeclaration(ir::VariableDeclaration *va if (!varDecl->Annotations().empty()) { ArenaVector propAnnotations(allocator_->Adapter()); for (auto *annotationUsage : varDecl->Annotations()) { + ES2PANDA_ASSERT(annotationUsage != nullptr); propAnnotations.push_back(annotationUsage->Clone(allocator_, field)->AsAnnotationUsage()); } field->SetAnnotations(std::move(propAnnotations)); @@ -181,6 +183,7 @@ ir::ExpressionStatement *GlobalDeclTransformer::InitTopLevelProperty(ir::ClassPr initializer->SetParent(nullptr); auto *assignmentExpression = util::NodeAllocator::Alloc( allocator_, ident, initializer, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(assignmentExpression != nullptr); assignmentExpression->SetRange({ident->Start(), initializer->End()}); assignmentExpression->SetTsType(initializer->TsType()); diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp index aa94648858..c7b88afa10 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.cpp @@ -161,6 +161,7 @@ void ImportExportDecls::HandleSelectiveExportWithAlias(util::StringView original !declItem->second->HasExportAlias(); if (!alreadyExported && declItem->second->IsVariableDeclaration()) { auto declarator = declItem->second->AsVariableDeclaration()->GetDeclaratorByName(exportName); + ES2PANDA_ASSERT(declarator != nullptr); alreadyExported |= ((declarator->Modifiers() & ir::ModifierFlags::EXPORTED) != 0) && !declarator->HasExportAlias(); } diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h index 27b17db341..c873e8ffdb 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/importExportDecls.h @@ -155,7 +155,7 @@ private: exportMap.insert({program_->SourceFilePath(), newMap}); } - void RestoreImportExportDecls() + void RestoreImportExportDecls() noexcept { imExDecl_->fieldMap_ = fieldMapPrev_; imExDecl_->exportNameMap_ = exportNameMapPrev_; diff --git a/ets2panda/compiler/lowering/ets/unionLowering.cpp b/ets2panda/compiler/lowering/ets/unionLowering.cpp index 61cacd86a4..aba0545179 100644 --- a/ets2panda/compiler/lowering/ets/unionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unionLowering.cpp @@ -62,6 +62,7 @@ static ir::ClassDefinition *GetUnionAccessClass(public_lib::Context *ctx, varbin auto classCtx = varbinder::LexicalScope(varbinder); auto *classDef = ctx->AllocNode(ctx->Allocator(), ident, ir::ClassDefinitionModifiers::GLOBAL, ir::ModifierFlags::ABSTRACT, Language(Language::Id::ETS)); + ES2PANDA_ASSERT(classDef != nullptr); classDef->SetScope(classCtx.GetScope()); auto *classDecl = ctx->AllocNode(classDef, allocator); classDef->Scope()->BindNode(classDecl->Definition()); @@ -103,6 +104,7 @@ static std::tuple CreateNamedA nullptr, ir::FunctionSignature(nullptr, std::move(params), returnTypeAnno), // CC-OFFNXT(G.FMT.02-CPP) project code style ir::ScriptFunctionFlags::METHOD, ir::ModifierFlags::PUBLIC}); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(methodIdent->Clone(allocator, nullptr)); // Create the synthetic function node @@ -146,7 +148,7 @@ static varbinder::LocalVariable *CreateNamedAccessProperty(public_lib::Context * // Create the synthetic class property node auto *field = ctx->AllocNode(fieldIdent, nullptr, nullptr, ir::ModifierFlags::NONE, allocator, false); - + ES2PANDA_ASSERT(field != nullptr); // Add the declaration to the scope auto [decl, var] = varbinder->NewVarDecl(fieldIdent->Start(), fieldIdent->Name()); var->AddFlag(varbinder::VariableFlags::PROPERTY); @@ -167,8 +169,9 @@ static varbinder::LocalVariable *CreateNamedAccess(public_lib::Context *ctx, var auto type = expr->TsType(); auto name = expr->Property()->AsIdentifier()->Name(); auto *checker = ctx->GetChecker()->AsETSChecker(); - - auto unionType = checker->GetApparentType(checker->GetNonNullishType(expr->Object()->TsType()))->AsETSUnionType(); + auto *apparentType = checker->GetApparentType(checker->GetNonNullishType(expr->Object()->TsType())); + ES2PANDA_ASSERT(apparentType != nullptr); + auto unionType = apparentType->AsETSUnionType(); auto *const accessClass = GetUnionAccessClass(ctx, varbinder, GetAccessClassName(unionType)); auto *classScope = accessClass->Scope()->AsClassScope(); diff --git a/ets2panda/ir/statements/annotationUsage.cpp b/ets2panda/ir/statements/annotationUsage.cpp index c67884104a..1183e94543 100644 --- a/ets2panda/ir/statements/annotationUsage.cpp +++ b/ets2panda/ir/statements/annotationUsage.cpp @@ -58,6 +58,7 @@ void AnnotationUsage::Dump(ir::SrcDumper *dumper) const if (!properties_.empty()) { dumper->Add("{"); for (auto elem : properties_) { + ES2PANDA_ASSERT(elem->AsClassProperty()->Id() != nullptr); dumper->Add(elem->AsClassProperty()->Id()->Name().Mutf8()); dumper->Add(":"); elem->AsClassProperty()->Value()->Dump(dumper); @@ -74,6 +75,7 @@ AnnotationUsage *AnnotationUsage::Clone(ArenaAllocator *const allocator, AstNode { auto *const expr = expr_ != nullptr ? expr_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(expr, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (expr != nullptr) { expr->SetParent(clone); diff --git a/ets2panda/ir/statements/blockStatement.cpp b/ets2panda/ir/statements/blockStatement.cpp index abbe7d12b0..63f18d40c1 100644 --- a/ets2panda/ir/statements/blockStatement.cpp +++ b/ets2panda/ir/statements/blockStatement.cpp @@ -48,6 +48,7 @@ AstNode *BlockStatement::Clone(ArenaAllocator *const allocator, AstNode *const p } auto retVal = util::NodeAllocator::ForceSetParent(allocator, allocator, std::move(statements)); + ES2PANDA_ASSERT(retVal != nullptr); retVal->SetParent(parent); return retVal; diff --git a/ets2panda/ir/statements/breakStatement.cpp b/ets2panda/ir/statements/breakStatement.cpp index 3a8b44bde4..afbca163d3 100644 --- a/ets2panda/ir/statements/breakStatement.cpp +++ b/ets2panda/ir/statements/breakStatement.cpp @@ -79,6 +79,7 @@ BreakStatement *BreakStatement::Clone(ArenaAllocator *const allocator, AstNode * { auto *const ident = ident_ != nullptr ? ident_->Clone(allocator, nullptr) : nullptr; auto *const clone = util::NodeAllocator::ForceSetParent(allocator, ident); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/statements/continueStatement.cpp b/ets2panda/ir/statements/continueStatement.cpp index 89bacf1b71..8b73763a7d 100644 --- a/ets2panda/ir/statements/continueStatement.cpp +++ b/ets2panda/ir/statements/continueStatement.cpp @@ -73,6 +73,7 @@ ContinueStatement *ContinueStatement::Clone(ArenaAllocator *const allocator, Ast { auto *const ident = ident_ != nullptr ? ident_->Clone(allocator, nullptr) : nullptr; auto *const clone = util::NodeAllocator::ForceSetParent(allocator, ident); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/statements/forOfStatement.cpp b/ets2panda/ir/statements/forOfStatement.cpp index e6183c6b5c..34147d4f7c 100644 --- a/ets2panda/ir/statements/forOfStatement.cpp +++ b/ets2panda/ir/statements/forOfStatement.cpp @@ -120,6 +120,7 @@ ForOfStatement *ForOfStatement::Clone(ArenaAllocator *const allocator, AstNode * auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const body = body_ != nullptr ? body_->Clone(allocator, nullptr)->AsStatement() : nullptr; auto *const clone = allocator->New(left, right, body, isAwait_); + ES2PANDA_ASSERT(clone != nullptr); if (left != nullptr) { left->SetParent(clone); diff --git a/ets2panda/ir/statements/tryStatement.cpp b/ets2panda/ir/statements/tryStatement.cpp index 7281fa5e60..82d74865c4 100644 --- a/ets2panda/ir/statements/tryStatement.cpp +++ b/ets2panda/ir/statements/tryStatement.cpp @@ -127,9 +127,21 @@ TryStatement::TryStatement(TryStatement const &other, ArenaAllocator *allocator) { block_ = other.block_ == nullptr ? nullptr : other.block_->Clone(allocator, this)->AsBlockStatement(); for (auto &cc : other.catchClauses_) { - catchClauses_.push_back(cc == nullptr ? nullptr : cc->Clone(allocator, this)->AsCatchClause()); + if (cc == nullptr) { + catchClauses_.push_back(nullptr); + continue; + } + auto *ccClone = cc->Clone(allocator, this); + ES2PANDA_ASSERT(ccClone != nullptr); + catchClauses_.push_back(ccClone->AsCatchClause()); + } + if (other.finalizer_ == nullptr) { + finalizer_ = nullptr; + } else { + auto *otherFinalizerClone = other.finalizer_->Clone(allocator, this); + ES2PANDA_ASSERT(otherFinalizerClone != nullptr); + finalizer_ = otherFinalizerClone->AsBlockStatement(); } - finalizer_ = other.finalizer_ == nullptr ? nullptr : other.finalizer_->Clone(allocator, this)->AsBlockStatement(); for (auto &[label, st] : other.finalizerInsertions_) { finalizerInsertions_.emplace_back(label, st); } @@ -138,6 +150,7 @@ TryStatement::TryStatement(TryStatement const &other, ArenaAllocator *allocator) TryStatement *TryStatement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/statements/variableDeclaration.cpp b/ets2panda/ir/statements/variableDeclaration.cpp index adbe853c54..fd09dc88e4 100644 --- a/ets2panda/ir/statements/variableDeclaration.cpp +++ b/ets2panda/ir/statements/variableDeclaration.cpp @@ -211,7 +211,9 @@ VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, Variabl } for (auto const &d : other.declarators_) { - declarators_.emplace_back(d->Clone(allocator, nullptr)->AsVariableDeclarator()); + auto *dClone = d->Clone(allocator, nullptr); + ES2PANDA_ASSERT(dClone != nullptr); + declarators_.emplace_back(dClone->AsVariableDeclarator()); declarators_.back()->SetParent(this); } @@ -246,6 +248,7 @@ VariableDeclaration::VariableDeclaration([[maybe_unused]] Tag const tag, Variabl VariableDeclaration *VariableDeclaration::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/statements/variableDeclarator.cpp b/ets2panda/ir/statements/variableDeclarator.cpp index 02780398c0..621d394dbd 100644 --- a/ets2panda/ir/statements/variableDeclarator.cpp +++ b/ets2panda/ir/statements/variableDeclarator.cpp @@ -76,6 +76,7 @@ VariableDeclarator *VariableDeclarator::Clone(ArenaAllocator *const allocator, A auto *const id = id_ != nullptr ? id_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const init = init_ != nullptr ? init_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(flag_, id, init); + ES2PANDA_ASSERT(clone != nullptr); if (id != nullptr) { id->SetParent(clone); diff --git a/ets2panda/parser/TSparser.cpp b/ets2panda/parser/TSparser.cpp index 164f34c170..98823e5ef4 100644 --- a/ets2panda/parser/TSparser.cpp +++ b/ets2panda/parser/TSparser.cpp @@ -734,6 +734,7 @@ ir::TSTypeParameter *TSParser::ParseMappedTypeParameter() lexer::SourcePosition startLoc = Lexer()->GetToken().Start(); auto *paramName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(paramName != nullptr); paramName->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -891,6 +892,7 @@ ir::TypeNode *TSParser::ParseTypeLiteralOrMappedType(ir::TypeNode *typeAnnotatio Lexer()->NextToken(); auto *literalType = AllocNode(std::move(members), Allocator()); + ES2PANDA_ASSERT(literalType != nullptr); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, literalType); literalType->SetVariable(typeVar); literalType->SetRange({bodyStart, bodyEnd}); @@ -1998,6 +2000,7 @@ std::tuple TSParser::ParseComputedClassFieldOrIndexSignature(i if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT && Lexer()->Lookahead() == lexer::LEX_CHAR_COLON) { auto id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat param diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index ec8975b8d6..96c9c1508f 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -197,6 +197,7 @@ ir::TSTypeAssertion *TypedParser::ParseTypeAssertion() Lexer()->NextToken(); // eat '>' ir::Expression *expression = ParseExpression(); auto *typeAssertion = AllocNode(typeAnnotation, expression); + ES2PANDA_ASSERT(typeAssertion != nullptr); typeAssertion->SetRange({start, Lexer()->GetToken().End()}); return typeAssertion; @@ -310,6 +311,7 @@ ir::TSModuleDeclaration *TypedParser::ParseAmbientExternalModuleDeclaration(cons auto *moduleDecl = AllocNode(Allocator(), name, body, ir::TSModuleDeclaration::ConstructorFlags {isGlobal, true}); + ES2PANDA_ASSERT(moduleDecl != nullptr); moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()}); return moduleDecl; @@ -322,6 +324,7 @@ ir::TSModuleDeclaration *TypedParser::ParseModuleOrNamespaceDeclaration(const le } auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -354,6 +357,7 @@ ir::TSModuleBlock *TypedParser::ParseTsModuleBlock() auto statements = ParseStatementList(); auto *blockNode = AllocNode(std::move(statements)); + ES2PANDA_ASSERT(blockNode != nullptr); blockNode->SetRange({startLoc, Lexer()->GetToken().End()}); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); @@ -430,6 +434,7 @@ ir::TypeNode *TypedParser::ParseInterfaceExtendsElement() if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; typeParamInst = ParseTypeParameterInstantiation(&options); + ES2PANDA_ASSERT(typeParamInst != nullptr); heritageEnd = typeParamInst->End(); } @@ -446,7 +451,9 @@ ArenaVector TypedParser::ParseInterfaceExtendsClause( while (true) { auto *typeReference = ParseInterfaceExtendsElement(); + ES2PANDA_ASSERT(typeReference != nullptr); auto *heritage = AllocNode(typeReference); + ES2PANDA_ASSERT(heritage != nullptr); heritage->SetRange(typeReference->Range()); extends.push_back(heritage); @@ -506,6 +513,7 @@ ir::Statement *TypedParser::ParseInterfaceDeclaration(bool isStatic) Allocator(), std::move(extends), ir::TSInterfaceDeclaration::ConstructorData {id, typeParamDecl, body, isStatic, isExternal, GetContext().GetLanguage()}); + ES2PANDA_ASSERT(interfaceDecl != nullptr); interfaceDecl->SetRange({interfaceStart, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -705,6 +713,7 @@ ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const auto *enumDeclaration = AllocNode(Allocator(), key, std::move(members), ir::TSEnumDeclaration::ConstructorFlags {isConst}); + ES2PANDA_ASSERT(enumDeclaration != nullptr); enumDeclaration->SetRange({enumStart, endLoc}); return enumDeclaration; @@ -741,7 +750,7 @@ ir::TSTypeParameter *TypedParser::ParseTypeParameter(TypeAnnotationParsingOption const auto &ident = Lexer()->GetToken().Ident(); auto *paramIdent = AllocNode(ident, Allocator()); - + ES2PANDA_ASSERT(paramIdent != nullptr); paramIdent->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -900,6 +909,7 @@ ArenaVector TypedParser::ParseClassImplementClause() lexer::SourcePosition implStart = Lexer()->GetToken().Start(); auto [expr, implTypeParams] = ParseClassImplementsElement(); auto *impl = AllocNode(expr, implTypeParams); + ES2PANDA_ASSERT(impl != nullptr); impl->SetRange({implStart, Lexer()->GetToken().End()}); implements.push_back(impl); @@ -985,6 +995,7 @@ ir::ClassDefinition *TypedParser::ParseClassDefinition(ir::ClassDefinitionModifi auto *classDefinition = AllocNode(identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetInternalName(privateBinding.View()); classDefinition->SetRange(bodyRange); @@ -1018,7 +1029,7 @@ ir::AstNode *TypedParser::ParseProperty(const ArenaVector &proper property = AllocNode(propName, typeAnnotation, desc.modifiers & ir::ModifierFlags::READONLY); - + ES2PANDA_ASSERT(property != nullptr); property->SetRange({property->AsTSIndexSignature()->Param()->Start(), property->AsTSIndexSignature()->TypeAnnotation()->End()}); } else { @@ -1029,7 +1040,7 @@ ir::AstNode *TypedParser::ParseProperty(const ArenaVector &proper if (desc.isPrivateIdent) { LogError(diagnostic::DECORATORS_INVALID); } - + ES2PANDA_ASSERT(property != nullptr); property->AddDecorators(std::move(desc.decorators)); } } @@ -1215,6 +1226,7 @@ ir::Expression *TypedParser::ParseQualifiedName(ExpressionParseFlags flags) break; case lexer::TokenType::LITERAL_IDENT: expr = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(expr != nullptr); expr->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); break; @@ -1272,6 +1284,7 @@ ir::Expression *TypedParser::ParseQualifiedReference(ir::Expression *typeName, E propName->SetRange(Lexer()->GetToken().Loc()); typeName = AllocNode(typeName, propName, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange({typeName->AsTSQualifiedName()->Left()->Start(), Lexer()->GetToken().End()}); if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 67500b59ac..2f9b9e3cee 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -774,6 +774,7 @@ ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral() } auto *templateNode = AllocNode(std::move(quasis), std::move(expressions), multilineStr); + ES2PANDA_ASSERT(templateNode != nullptr); templateNode->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index d8701598bd..d2ee06562b 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -216,6 +216,7 @@ public: Variable *AddDecl(ArenaAllocator *allocator, Decl *decl, ScriptExtension extension) { + ES2PANDA_ASSERT(decl != nullptr); auto *var = AddBinding(allocator, FindLocal(decl->Name(), varbinder::ResolveBindingOptions::BINDINGS), decl, extension); if (var != nullptr) { @@ -873,6 +874,7 @@ public: { auto *paramScope = allocator->New(allocator, this); paramScope_ = paramScope; + ES2PANDA_ASSERT(paramScope_ != nullptr); paramScope_->BindFunctionScope(this); } @@ -979,7 +981,7 @@ std::pair Scope::AddDecl(ArenaAllocator *allocator, auto *decl = allocator->New(name); variable = allocator->New(decl, flags); - + ES2PANDA_ASSERT(variable != nullptr); decls_.emplace_back(decl); bindings_.insert({decl->Name(), variable}); variable->SetScope(this); diff --git a/ets2panda/varbinder/varbinder.cpp b/ets2panda/varbinder/varbinder.cpp index fc48436145..0c8e39ff4e 100644 --- a/ets2panda/varbinder/varbinder.cpp +++ b/ets2panda/varbinder/varbinder.cpp @@ -145,7 +145,7 @@ void VarBinder::InstantiateArguments() auto *iter = scope_; while (true) { Scope *scope = iter->IsFunctionParamScope() ? iter : iter->EnclosingVariableScope(); - + ES2PANDA_ASSERT(scope != nullptr); const auto *node = scope->Node(); if (scope->IsLoopScope()) { @@ -172,7 +172,7 @@ void VarBinder::PropagateDirectEval() const do { VariableScope *scope = iter->IsFunctionParamScope() ? iter->AsFunctionParamScope()->GetFunctionScope() : iter->EnclosingVariableScope(); - + ES2PANDA_ASSERT(scope != nullptr); scope->AddFlag(ScopeFlags::NO_REG_STORE); iter = iter->Parent(); } while (iter != nullptr); @@ -185,7 +185,7 @@ void VarBinder::InstantiatePrivateContext(const ir::Identifier *ident) const while (classDef != nullptr) { auto *scope = classDef->Scope(); Variable *variable = scope->FindLocal(classDef->InternalName(), varbinder::ResolveBindingOptions::BINDINGS); - + ES2PANDA_ASSERT(variable != nullptr); if (!variable->HasFlag(VariableFlags::INITIALIZED)) { break; } @@ -328,6 +328,7 @@ void VarBinder::BuildVarDeclarator(ir::VariableDeclarator *varDecl) void VarBinder::BuildClassProperty(const ir::ClassProperty *prop) { const ir::ScriptFunction *ctor = util::Helpers::GetContainingConstructor(prop); + ES2PANDA_ASSERT(ctor != nullptr); auto scopeCtx = LexicalScope::Enter(this, ctor->Scope()); ResolveReferences(prop); @@ -363,6 +364,7 @@ void VarBinder::BuildClassDefinition(ir::ClassDefinition *classDef) } Variable *variable = scope_->FindLocal(classDef->InternalName(), varbinder::ResolveBindingOptions::BINDINGS); + ES2PANDA_ASSERT(variable != nullptr); variable->AddFlag(VariableFlags::INITIALIZED); if (classDef->Ident() != nullptr) { @@ -536,6 +538,7 @@ void VarBinder::ResolveReference(ir::AstNode *childNode) LookupIdentReference(childNode->AsIdentifier()); return ResolveReferences(childNode); case ir::AstNodeType::SUPER_EXPRESSION: + ES2PANDA_ASSERT(scope_->EnclosingVariableScope() != nullptr); scope_->EnclosingVariableScope()->AddFlag(ScopeFlags::USE_SUPER); return ResolveReferences(childNode); case ir::AstNodeType::SCRIPT_FUNCTION: { diff --git a/ets2panda/varbinder/variable.cpp b/ets2panda/varbinder/variable.cpp index f58fab3472..66885f4f0c 100644 --- a/ets2panda/varbinder/variable.cpp +++ b/ets2panda/varbinder/variable.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2025 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -41,6 +41,7 @@ const util::StringView &Variable::Name() const LocalVariable *LocalVariable::Copy(ArenaAllocator *allocator, Decl *decl) const { auto *var = allocator->New(decl, flags_); + ES2PANDA_ASSERT(var != nullptr); var->vreg_ = vreg_; return var; } @@ -52,7 +53,7 @@ void LocalVariable::SetLexical(Scope *scope) } VariableScope *varScope = scope->EnclosingVariableScope(); - + ES2PANDA_ASSERT(varScope != nullptr); BindLexEnvSlot(varScope->NextSlot()); } -- Gitee From 542661687909e73799da584bc90b4047fff39b91 Mon Sep 17 00:00:00 2001 From: Daniel Kofanov Date: Fri, 27 Jun 2025 03:48:04 +0800 Subject: [PATCH 006/107] [ArkTS] Enable no-primitives invariant Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICI4WX?from=project-issue Change-Id: I46e78308ccb5be4b356a4098d68783395da616f4 Signed-off-by: Daniel Kofanov --- ets2panda/ast_verifier/ASTVerifier.h | 3 ++- ets2panda/ast_verifier/invariants/nodeHasType.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/ets2panda/ast_verifier/ASTVerifier.h b/ets2panda/ast_verifier/ASTVerifier.h index 9aaa1aecc3..1bd190ef76 100644 --- a/ets2panda/ast_verifier/ASTVerifier.h +++ b/ets2panda/ast_verifier/ASTVerifier.h @@ -129,7 +129,8 @@ public: i <= VerifierInvariants::AFTER_CHECKER_PHASE_LAST; i++) { allowed_[i] = true; } - // NOTE(dkofanov): This should be called after "NumberLowering" phase: + } + if (occurredPhaseName == "Unbox") { Get()->SetNumberLoweringOccured(); } if (occurredPhaseName == "UnionLowering") { diff --git a/ets2panda/ast_verifier/invariants/nodeHasType.h b/ets2panda/ast_verifier/invariants/nodeHasType.h index 81769166cf..edfee888c3 100644 --- a/ets2panda/ast_verifier/invariants/nodeHasType.h +++ b/ets2panda/ast_verifier/invariants/nodeHasType.h @@ -49,7 +49,8 @@ public: if (type == nullptr) { return {CheckDecision::CORRECT, CheckAction::CONTINUE}; } - if (!numberLoweringOccurred_ && type->IsETSPrimitiveType()) { + // NOTE(dkofanov): Broken extension functions. + if (!numberLoweringOccurred_ && !type->IsETSExtensionFuncHelperType() && type->IsETSPrimitiveType()) { AddCheckMessage("PRIMITIVE_BEFORE_LOWERING", *ast); return {CheckDecision::INCORRECT, CheckAction::CONTINUE}; } -- Gitee From 79d39dc4697ca52fd3d03c0c9fd8ad4631af6329 Mon Sep 17 00:00:00 2001 From: zhongning5 Date: Sat, 28 Jun 2025 14:29:51 +0800 Subject: [PATCH 007/107] fix arkts-no-inferred-generic-params Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICICX6 Test scenarios:Fix bugs for arkts-no-inferred-generic-params Signed-off-by: zhongning5 --- ets2panda/linter/rule-config.json | 2 +- ets2panda/linter/src/lib/CookBookMsg.ts | 2 +- ets2panda/linter/src/lib/TypeScriptLinter.ts | 20 ++++---- .../test/main/func_inferred_type_args_2.ets | 12 ++++- .../func_inferred_type_args_2.ets.arkts2.json | 50 +++++++++++++++++++ ...func_inferred_type_args_2.ets.autofix.json | 50 +++++++++++++++++++ .../func_inferred_type_args_2.ets.migrate.ets | 12 ++++- ...func_inferred_type_args_2.ets.migrate.json | 50 +++++++++++++++++++ .../test/ohmurl/ohmurl_import.ets.arkts2.json | 10 ++-- .../ohmurl/ohmurl_import.ets.autofix.json | 10 ++-- 10 files changed, 195 insertions(+), 23 deletions(-) diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 86ed49ff43..21370cd2c5 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -123,7 +123,7 @@ "arkts-builtin-cotr" ], "OHMURL": [ - "arkts-ohmurl-full-path" + "arkts-require-fullpath-name" ], "sdk": [ "sdk-limited-void-type", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 31ef5659cb..ee3dd98206 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -291,7 +291,7 @@ cookBookTag[285] = '"setAndProp" function is not supported (arkui-no-setandprop- cookBookTag[286] = 'Parameters decorated with "@Prop" need to call the specific method when receiving data to ensure deep copy of the data (arkui-prop-need-call-method-for-deep-copy)'; cookBookTag[300] = 'The function type should be explicit (arkts-no-ts-like-function-call)'; -cookBookTag[301] = 'Importing from "oh module" requires specifying full path (arkts-ohmurl-full-path)'; +cookBookTag[301] = 'Importing from "oh module" requires specifying full path (arkts-require-fullpath-name)'; cookBookTag[302] = 'Class type is not compatible with "Object" parameter in interop call (arkts-interop-d2s-static-object-on-dynamic-instance)'; cookBookTag[303] = diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 1760649828..7e5377a104 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -4804,8 +4804,8 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private handleGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, - callSignature: ts.Signature + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, + callSignature?: ts.Signature ): void { /* @@ -4819,19 +4819,20 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.incrementCounters(callLikeExpr, FaultID.GenericCallNoTypeArgs, autofix); return; } - this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); + if (callSignature) { + this.checkTypeArgumentsForGenericCallWithNoTypeArgs(callLikeExpr, callSignature); + } } - private static isInvalidBuiltinGenericConstructorCall(newExpression: ts.CallExpression | ts.NewExpression): boolean { - if (!ts.isNewExpression(newExpression)) { - return false; - } + private static isInvalidBuiltinGenericConstructorCall( + newExpression: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments + ): boolean { const isBuiltin = BUILTIN_GENERIC_CONSTRUCTORS.has(newExpression.expression.getText().replace(/Constructor$/, '')); return isBuiltin && (!newExpression.typeArguments || newExpression.typeArguments.length === 0); } private checkTypeArgumentsForGenericCallWithNoTypeArgs( - callLikeExpr: ts.CallExpression | ts.NewExpression, + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, callSignature: ts.Signature ): void { if (ts.isNewExpression(callLikeExpr) && this.isNonGenericClass(callLikeExpr)) { @@ -4872,7 +4873,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private checkForUnknownTypeInNonArkTS2( - callLikeExpr: ts.CallExpression | ts.NewExpression, + callLikeExpr: ts.CallExpression | ts.NewExpression | ts.ExpressionWithTypeArguments, resolvedTypeArgs: ts.NodeArray, startTypeArg: number ): void { @@ -7141,6 +7142,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (node.token === ts.SyntaxKind.ExtendsKeyword || node.token === ts.SyntaxKind.ImplementsKeyword) { node.types.forEach((type) => { const expr = type.expression; + this.handleGenericCallWithNoTypeArgs(type); if (ts.isCallExpression(expr)) { this.incrementCounters(expr, FaultID.ExtendsExpression); return; diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets index 0df022ea8f..80246fcd42 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets @@ -107,4 +107,14 @@ class A { } else { } } -} \ No newline at end of file +} +class SubArr extends Array {} +let subArr = new SubArr(); +class SubSet extends Set{} +let subSet = new SubSet(); +class SubMap extends Map{} +let subMap = new SubMap(); +class SubWeakMap extends WeakMap{} +let subWeakMap = new SubWeakMap(); +class SubWeakSet extends WeakSet{} +let subWeakSet = new SubWeakSet(); diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json index 91c50bde47..d1ca60d4ff 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.arkts2.json @@ -484,6 +484,56 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, + { + "line": 111, + "column": 22, + "endLine": 111, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 22, + "endLine": 113, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 22, + "endLine": 115, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, { "line": 84, "column": 2, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json index f32d5755fd..c53b7da247 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.autofix.json @@ -748,6 +748,56 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, + { + "line": 111, + "column": 22, + "endLine": 111, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 113, + "column": 22, + "endLine": 113, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 115, + "column": 22, + "endLine": 115, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 117, + "column": 26, + "endLine": 117, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 119, + "column": 26, + "endLine": 119, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, { "line": 84, "column": 2, diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets index 92362e1c98..12acc316b7 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.ets @@ -114,4 +114,14 @@ class A { } else { } } -} \ No newline at end of file +} +class SubArr extends Array {} +let subArr = new SubArr(); +class SubSet extends Set{} +let subSet = new SubSet(); +class SubMap extends Map{} +let subMap = new SubMap(); +class SubWeakMap extends WeakMap{} +let subWeakMap = new SubWeakMap(); +class SubWeakSet extends WeakSet{} +let subWeakSet = new SubWeakSet(); diff --git a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json index e45393b94a..0b10990af1 100644 --- a/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json +++ b/ets2panda/linter/test/main/func_inferred_type_args_2.ets.migrate.json @@ -244,6 +244,56 @@ "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", "severity": "ERROR" }, + { + "line": 118, + "column": 22, + "endLine": 118, + "endColumn": 27, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 120, + "column": 22, + "endLine": 120, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 122, + "column": 22, + "endLine": 122, + "endColumn": 25, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 124, + "column": 26, + "endLine": 124, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 126, + "column": 26, + "endLine": 126, + "endColumn": 33, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, { "line": 110, "column": 22, diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json index 04102fd8c9..38bbc17073 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.arkts2.json @@ -21,7 +21,7 @@ "endColumn": 60, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -31,7 +31,7 @@ "endColumn": 56, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -41,7 +41,7 @@ "endColumn": 45, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -51,7 +51,7 @@ "endColumn": 52, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -61,7 +61,7 @@ "endColumn": 48, "problem": "OhmUrlFullPath", "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json index dee154796f..c81032fb95 100644 --- a/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json +++ b/ets2panda/linter/test/ohmurl/ohmurl_import.ets.autofix.json @@ -28,7 +28,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -45,7 +45,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -62,7 +62,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -79,7 +79,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" }, { @@ -96,7 +96,7 @@ } ], "suggest": "", - "rule": "Importing from \"oh module\" requires specifying full path (arkts-ohmurl-full-path)", + "rule": "Importing from \"oh module\" requires specifying full path (arkts-require-fullpath-name)", "severity": "ERROR" } ] -- Gitee From eff969bcba2a8256b92161a2015ce4abf893c807 Mon Sep 17 00:00:00 2001 From: wangjiahui Date: Wed, 2 Jul 2025 11:34:25 +0800 Subject: [PATCH 008/107] tdd coverage fix Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJDCC Test scenarios:tdd coverage fix Signed-off-by: wangjiahui --- .../scripts/testRunner/coverage_collect.js | 92 +++++++++++++++++-- .../scripts/testRunner/coverage_report.js | 68 +++++++++----- 2 files changed, 126 insertions(+), 34 deletions(-) diff --git a/ets2panda/linter/scripts/testRunner/coverage_collect.js b/ets2panda/linter/scripts/testRunner/coverage_collect.js index c5a918cb5c..4bb11762d4 100644 --- a/ets2panda/linter/scripts/testRunner/coverage_collect.js +++ b/ets2panda/linter/scripts/testRunner/coverage_collect.js @@ -33,8 +33,14 @@ function processStatementMap(statementMap, consumer) { const startPos = consumer.originalPositionFor(statement.start); const endPos = consumer.originalPositionFor(statement.end); - statement.start = { line: startPos.line, column: startPos.column }; - statement.end = { line: endPos.line, column: endPos.column }; + statement.start = { + line: startPos.line, + column: 0 + }; + statement.end = { + line: endPos.line, + column: Number.MAX_SAFE_INTEGER + }; } } @@ -49,17 +55,21 @@ function processFunctionMap(functionMap, consumer) { const declStart = consumer.originalPositionFor(func.decl.start); const declEnd = consumer.originalPositionFor(func.decl.end); - const locStart = consumer.originalPositionFor(func.loc.start); - const locEnd = consumer.originalPositionFor(func.loc.end); func.decl = { - start: { line: declStart.line, column: declStart.column }, - end: { line: declEnd.line, column: declEnd.column } + start: { + line: declStart.line, + column: 0 + }, + end: { + line: declEnd.line, + column: Number.MAX_SAFE_INTEGER + } }; func.loc = { - start: { line: locStart.line, column: locStart.column }, - end: { line: locEnd.line, column: locEnd.column } + start: { line: declStart.line, column: 0 }, + end: { line: declEnd.line, column: Number.MAX_SAFE_INTEGER } }; func.line = declStart.line; @@ -97,6 +107,68 @@ function processBranchMap(branchMap, consumer) { } } + +/** + * Filter out coverage data before line 16 and remove function declaration coverage + * @param {Object} newCoverageData Original coverage data + * @returns {Object} Filtered coverage data + */ +function filterCoverageByLine(newCoverageData) { + const filteredCoverage = {}; + for (const filePath in newCoverageData) { + const fileCoverage = newCoverageData[filePath]; + const filteredFileCoverage = { + ...fileCoverage, + statementMap: {}, + fnMap: {}, + branchMap: {}, + s: {}, + f: {}, + b: {} + }; + for (const stmtId in fileCoverage.statementMap) { + const stmt = fileCoverage.statementMap[stmtId]; + if (stmt.start.line >= 16) { + filteredFileCoverage.statementMap[stmtId] = stmt; + filteredFileCoverage.s[stmtId] = fileCoverage.s[stmtId]; + } + } + for (const fnId in fileCoverage.fnMap) { + const fn = fileCoverage.fnMap[fnId]; + if (fn.decl.start.line >= 16) { + const newFn = { + ...fn, + decl: null, + loc: { + start: { + line: fn.decl.end.line + 1, + column: 0 + }, + end: fn.loc.end + }, + line: fn.decl.end.line + 1 + }; + filteredFileCoverage.fnMap[fnId] = newFn; + filteredFileCoverage.f[fnId] = fileCoverage.f[fnId]; + } + } + for (const branchId in fileCoverage.branchMap) { + const branch = fileCoverage.branchMap[branchId]; + if (branch.loc.start.line >= 16) { + filteredFileCoverage.branchMap[branchId] = branch; + filteredFileCoverage.b[branchId] = fileCoverage.b[branchId]; + } + } + if (Object.keys(filteredFileCoverage.statementMap).length > 0 || + Object.keys(filteredFileCoverage.fnMap).length > 0 || + Object.keys(filteredFileCoverage.branchMap).length > 0) { + filteredCoverage[filePath] = filteredFileCoverage; + } + } + return filteredCoverage; +} + + /** * Collects and processes coverage data using source maps */ @@ -132,9 +204,11 @@ async function collectCoverage() { }); } + const filteredCoverage = filterCoverageByLine(newCoverageData); + fs.writeFileSync( NEW_COVERAGE_FILE, - JSON.stringify(newCoverageData, null, 4) + JSON.stringify(filteredCoverage, null, 4) ); } diff --git a/ets2panda/linter/scripts/testRunner/coverage_report.js b/ets2panda/linter/scripts/testRunner/coverage_report.js index 84fa3219d0..134a0f3e81 100644 --- a/ets2panda/linter/scripts/testRunner/coverage_report.js +++ b/ets2panda/linter/scripts/testRunner/coverage_report.js @@ -12,45 +12,63 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - const fs = require('fs'); const path = require('path'); const libCoverage = require('istanbul-lib-coverage'); const libReport = require('istanbul-lib-report'); const reports = require('istanbul-reports'); -const projectRoot = path.join(__dirname, '..', '..'); +const projectRoot = path.resolve(__dirname, '../..'); const coverageDir = path.join(projectRoot, 'coverage'); +const reportDir = path.join(coverageDir, 'arkcompiler/ets_frontend/ets2panda/linter/src'); +const ABS_REPORT_DIR = 'arkcompiler/ets_frontend/ets2panda/linter/src'; -const coverageFile = fs.readFileSync(path.join(coverageDir, 'newCoverage.json'), 'utf8'); -const coverageData = JSON.parse(coverageFile); -const coverageMap = libCoverage.createCoverageMap(coverageData); +const coverageFile = path.join(coverageDir, 'newCoverage.json'); +if (!fs.existsSync(coverageFile)) { + throw new Error(`Coverage file not found: ${coverageFile}`); +} + +const coverageData = JSON.parse(fs.readFileSync(coverageFile, 'utf8')); -// create summary report -const summary = libCoverage.createCoverageSummary(); -coverageMap.files().forEach(file => { - const fc = coverageMap.fileCoverageFor(file); - const s = fc.toSummary(); - summary.merge(s); +Object.keys(coverageData).forEach(filePath => { + coverageData[filePath].fullPath = path.resolve(projectRoot, filePath); }); -console.log(summary); -// Watermarks for the report -const configWatermarks = { +const coverageMap = libCoverage.createCoverageMap(coverageData); +console.log(coverageMap); +const context = libReport.createContext({ + dir: reportDir, + watermarks: { statements: [50, 80], branches: [50, 80], functions: [50, 80], - lines: [50, 80], -}; -const context = libReport.createContext({ - dir: path.join(coverageDir, 'report-html'), - defaultSummarizer: 'nested', - watermarks: configWatermarks, - coverageMap, + lines: [50, 80] + }, + coverageMap }); -const report = reports.create('html', {}); -report.execute(context); +reports.create('html', {}).execute(context); + +function enhanceHtmlReports() { + const indexPath = path.join(reportDir, 'index.html'); + if (!fs.existsSync(indexPath)) + { + return; + } + + let html = fs.readFileSync(indexPath, 'utf8'); + + html = html.replace( + /(.+?)<\/a>/g, + (match, link, name) => { + const absPath = path.join(ABS_REPORT_DIR, link.replace('/index.html', '')); + return `${absPath}`; + } + ); + + fs.writeFileSync(indexPath, html); + console.log(`Added full paths to: ${indexPath}`); +} -const report_text = reports.create('text', {}); -report_text.execute(context); \ No newline at end of file +enhanceHtmlReports(); +console.log(`View coverage at: file://${reportDir}/index.html`); \ No newline at end of file -- Gitee From 7863aafb6ff214fba6c0f6e24dbe0e691241b073 Mon Sep 17 00:00:00 2001 From: zhongning Date: Wed, 2 Jul 2025 15:49:21 +0800 Subject: [PATCH 009/107] fix bug for arkts-no-lazy-import Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJ9CS Test scenarios:new tests update to the linter Signed-off-by: zhongning --- .../linter/src/lib/autofixes/Autofixer.ts | 12 +- ets2panda/linter/test/main/lazy_import.ets | 18 ++ .../test/main/lazy_import.ets.args.json | 3 +- .../test/main/lazy_import.ets.arkts2.json | 80 ++++++++ .../test/main/lazy_import.ets.autofix.json | 180 +++++++++++++++++- .../test/main/lazy_import.ets.migrate.ets | 37 ++++ .../test/main/lazy_import.ets.migrate.json | 17 ++ 7 files changed, 334 insertions(+), 13 deletions(-) create mode 100644 ets2panda/linter/test/main/lazy_import.ets.migrate.ets create mode 100644 ets2panda/linter/test/main/lazy_import.ets.migrate.json diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index 323536e118..89864957e8 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -4599,16 +4599,8 @@ export class Autofixer { } fixImportClause(tsImportClause: ts.ImportClause): Autofix[] { - const newImportClause = ts.factory.createImportClause( - tsImportClause.isTypeOnly, - tsImportClause.name, - tsImportClause.namedBindings - ); - const replacementText = this.printer.printNode( - ts.EmitHint.Unspecified, - newImportClause, - tsImportClause.getSourceFile() - ); + void this; + const replacementText = tsImportClause.getText().replace(/\blazy\b\s*/, ""); return [{ start: tsImportClause.getStart(), end: tsImportClause.getEnd(), replacementText }]; } diff --git a/ets2panda/linter/test/main/lazy_import.ets b/ets2panda/linter/test/main/lazy_import.ets index a40b832b4f..86bb429ac0 100755 --- a/ets2panda/linter/test/main/lazy_import.ets +++ b/ets2panda/linter/test/main/lazy_import.ets @@ -17,3 +17,21 @@ import lazy { m } from 'module' import lazy { a, b } from 'module1' import { c } from 'module2' + +import lazy {worker} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import lazy {harTest} from "har1" // (arkts-no-lazy-import) + +import lazy {add} from "hsp1" // (arkts-no-lazy-import) + +/* test */ import lazy {WorkerEventListener} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import /* test */ lazy {WorkerEventTarget} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ lazy /* test */ {WorkerOptions} /* test */ from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import lazy {worker as wk} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ +lazy // (arkts-no-lazy-import) +/* test */ {worker as ttt} /* test */ from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.args.json b/ets2panda/linter/test/main/lazy_import.ets.args.json index aaabef1e0a..8186a08902 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.args.json +++ b/ets2panda/linter/test/main/lazy_import.ets.args.json @@ -15,6 +15,7 @@ ], "mode": { "arkts2": "", - "autofix": "--arkts-2" + "autofix": "--arkts-2", + "migrate": "--arkts-2" } } diff --git a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json index bd0dee6544..083eb8318e 100755 --- a/ets2panda/linter/test/main/lazy_import.ets.arkts2.json +++ b/ets2panda/linter/test/main/lazy_import.ets.arkts2.json @@ -33,6 +33,86 @@ "suggest": "", "rule": "Lazy import is not supported(arkts-no-lazy-import)", "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5, + "problem": "ImportLazyIdentifier", + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.autofix.json b/ets2panda/linter/test/main/lazy_import.ets.autofix.json index 765ce394d8..75ae26f1e3 100644 --- a/ets2panda/linter/test/main/lazy_import.ets.autofix.json +++ b/ets2panda/linter/test/main/lazy_import.ets.autofix.json @@ -24,7 +24,11 @@ { "start": 612, "end": 622, - "replacementText": "{ m }" + "replacementText": "{ m }", + "line": 16, + "column": 8, + "endLine": 16, + "endColumn": 12 } ], "suggest": "", @@ -41,7 +45,179 @@ { "start": 645, "end": 658, - "replacementText": "{ a, b }" + "replacementText": "{ a, b }", + "line": 18, + "column": 8, + "endLine": 18, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 710, + "end": 723, + "replacementText": "{worker}", + "line": 21, + "column": 8, + "endLine": 21, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 779, + "end": 793, + "replacementText": "{harTest}", + "line": 23, + "column": 8, + "endLine": 23, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 840, + "end": 850, + "replacementText": "{add}", + "line": 25, + "column": 8, + "endLine": 25, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 908, + "end": 934, + "replacementText": "{WorkerEventListener}", + "line": 27, + "column": 19, + "endLine": 27, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 999, + "end": 1023, + "replacementText": "{WorkerEventTarget}", + "line": 29, + "column": 19, + "endLine": 29, + "endColumn": 23 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1100, + "end": 1132, + "replacementText": "/* test */ {WorkerOptions}", + "line": 31, + "column": 31, + "endLine": 31, + "endColumn": 35 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1198, + "end": 1217, + "replacementText": "{worker as wk}", + "line": 33, + "column": 8, + "endLine": 33, + "endColumn": 12 + } + ], + "suggest": "", + "rule": "Lazy import is not supported(arkts-no-lazy-import)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5, + "problem": "ImportLazyIdentifier", + "autofix": [ + { + "start": 1293, + "end": 1355, + "replacementText": "// (arkts-no-lazy-import)\n/* test */ {worker as ttt}", + "line": 36, + "column": 1, + "endLine": 36, + "endColumn": 5 } ], "suggest": "", diff --git a/ets2panda/linter/test/main/lazy_import.ets.migrate.ets b/ets2panda/linter/test/main/lazy_import.ets.migrate.ets new file mode 100644 index 0000000000..2c02388768 --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.migrate.ets @@ -0,0 +1,37 @@ +/* + * 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. + */ + +import { m } from 'module' + +import { a, b } from 'module1' +import { c } from 'module2' + +import {worker} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import {harTest} from "har1" // (arkts-no-lazy-import) + +import {add} from "hsp1" // (arkts-no-lazy-import) + +/* test */ import {WorkerEventListener} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import /* test */ {WorkerEventTarget} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ /* test */ {WorkerOptions} /* test */ from '@kit.ArkTS'; // (arkts-no-lazy-import) + +import {worker as wk} from '@kit.ArkTS'; // (arkts-no-lazy-import) + +/* test */ import /* test */ +// (arkts-no-lazy-import) +/* test */ {worker as ttt} /* test */ from '@kit.ArkTS'; \ No newline at end of file diff --git a/ets2panda/linter/test/main/lazy_import.ets.migrate.json b/ets2panda/linter/test/main/lazy_import.ets.migrate.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/lazy_import.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file -- Gitee From dedd324fe29ba4da31f90176d44bd93748f2791c Mon Sep 17 00:00:00 2001 From: Templin Konstantin Date: Wed, 2 Jul 2025 14:13:49 +0300 Subject: [PATCH 010/107] Move proxy under namespace Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICGFO0 Signed-off-by: Templin Konstantin --- ets2panda/scripts/arkui.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index c765c20cbf..d3237cfb8b 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_8-fix-ani-array-api +ARKUI_DEV_BRANCH=panda_rev_8-move-proxy-under-namespace ARKUI_DEST=koala-sig -- Gitee From 6e85e5788373aa90214d959eeffc4ca9f933f624 Mon Sep 17 00:00:00 2001 From: Zhelyapov Aleksey Date: Mon, 30 Jun 2025 22:17:44 +0300 Subject: [PATCH 011/107] Fixed codecheck Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIYVN Signed-off-by: Zhelyapov Aleksey --- ets2panda/compiler/core/ETSGen.cpp | 33 ++++++++++++++++--- ets2panda/compiler/core/ETSGen.h | 3 +- ets2panda/compiler/core/function.cpp | 1 + .../lowering/scopesInit/scopesInitPhase.cpp | 10 ++++-- ets2panda/util/doubleLinkedList.h | 3 ++ ets2panda/util/generateBin.cpp | 1 + ets2panda/util/helpers.cpp | 1 + ets2panda/util/options.cpp | 1 + ets2panda/util/path.cpp | 8 ++--- ets2panda/util/ustring.h | 3 ++ ets2panda/varbinder/ETSBinder.cpp | 13 ++++++-- ets2panda/varbinder/scope.cpp | 9 +++-- 12 files changed, 70 insertions(+), 16 deletions(-) diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 4e62393a95..64969cbd23 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -86,6 +86,7 @@ void ETSGen::CompileAndCheck(const ir::Expression *expr) return; } + ES2PANDA_ASSERT(accType != nullptr); if (accType->IsETSPrimitiveType() && ((accType->TypeFlags() ^ exprType->TypeFlags()) & ~checker::TypeFlag::CONSTANT) == 0) { return; @@ -216,6 +217,7 @@ checker::Type const *ETSGen::TypeForVar(varbinder::Variable const *var) const no void ETSGen::MoveVreg(const ir::AstNode *const node, const VReg vd, const VReg vs) { const auto *const sourceType = GetVRegType(vs); + ES2PANDA_ASSERT(sourceType != nullptr); if (sourceType->IsETSReferenceType()) { Ra().Emit(node, vd, vs); @@ -247,6 +249,7 @@ void ETSGen::LoadVar(const ir::Identifier *node, varbinder::Variable const *cons break; } case ReferenceKind::FIELD: { + ES2PANDA_ASSERT(GetVRegType(GetThisReg()) != nullptr); const auto fullName = FormClassPropReference(GetVRegType(GetThisReg())->AsETSObjectType(), var->Name()); LoadProperty(node, var->TsType(), GetThisReg(), fullName); break; @@ -298,6 +301,7 @@ void ETSGen::StoreVar(const ir::Identifier *node, const varbinder::ConstScopeFin util::StringView ETSGen::FormClassPropReference(const checker::ETSObjectType *classType, const util::StringView &name) { std::stringstream ss; + ES2PANDA_ASSERT(classType != nullptr); ss << classType->AssemblerName().Mutf8() << Signatures::METHOD_SEPARATOR << name; return util::StringView(*ProgElement()->Strings().emplace(ss.str()).first); } @@ -345,6 +349,7 @@ static bool StaticAccessRequiresReferenceSafetyCheck(const ir::AstNode *const no void ETSGen::LoadStaticProperty(const ir::AstNode *const node, const checker::Type *propType, const util::StringView &fullName) { + ES2PANDA_ASSERT(propType != nullptr); if (propType->IsETSReferenceType()) { Sa().Emit(node, fullName); if (StaticAccessRequiresReferenceSafetyCheck(node, propType)) { @@ -362,6 +367,7 @@ void ETSGen::LoadStaticProperty(const ir::AstNode *const node, const checker::Ty void ETSGen::StoreProperty(const ir::AstNode *const node, const checker::Type *propType, const VReg objReg, const util::StringView &name) { + ES2PANDA_ASSERT(Checker()->GetApparentType(GetVRegType(objReg)) != nullptr); auto *objType = Checker()->GetApparentType(GetVRegType(objReg))->AsETSObjectType(); const auto fullName = FormClassPropReference(objType, name); @@ -574,6 +580,7 @@ void ETSGen::EmitReturnVoid(const ir::AstNode *node) void ETSGen::ReturnAcc(const ir::AstNode *node) { const auto *const accType = GetAccumulatorType(); + ES2PANDA_ASSERT(accType != nullptr); if (accType->IsETSReferenceType()) { Sa().Emit(node); @@ -586,6 +593,7 @@ void ETSGen::ReturnAcc(const ir::AstNode *node) static bool IsNullUnsafeObjectType(checker::Type const *type) { + ES2PANDA_ASSERT(type != nullptr); return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); } @@ -663,7 +671,7 @@ void ETSGen::BranchIfIsInstance(const ir::AstNode *const node, const VReg srcReg void ETSGen::IsInstance(const ir::AstNode *const node, const VReg srcReg, const checker::Type *target) { target = Checker()->GetApparentType(target); - ES2PANDA_ASSERT(target->IsETSReferenceType()); + ES2PANDA_ASSERT(target->IsETSReferenceType() && GetAccumulatorType() != nullptr); if (target->IsETSAnyType()) { // should be IsSupertypeOf(target, source) LoadAccumulatorBoolean(node, true); @@ -731,6 +739,7 @@ void ETSGen::CheckedReferenceNarrowingObject(const ir::AstNode *node, const chec bool nullishCheck = false; auto *source = GetAccumulatorType(); + ES2PANDA_ASSERT(source != nullptr); if (source->PossiblyETSUndefined()) { nullishCheck = true; BranchIfUndefined(node, isNullish); @@ -1470,6 +1479,7 @@ template void ETSGen::ResolveConditionalResultFloat(const ir::AstNode *node, Label *realEndLabel) { auto type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); VReg tmpReg = AllocReg(); StoreAccumulator(node, tmpReg); if (type->IsFloatType()) { @@ -1534,6 +1544,7 @@ void ETSGen::ResolveConditionalResultReference(const ir::AstNode *node) }; auto type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); if (!type->PossiblyETSString()) { Sa().Emit(node, 1); return; @@ -1548,6 +1559,7 @@ void ETSGen::ResolveConditionalResultReference(const ir::AstNode *node) compiler::VReg objReg = AllocReg(); StoreAccumulator(node, objReg); + ES2PANDA_ASSERT(Checker()->GlobalBuiltinETSStringType() != nullptr); EmitIsInstance(node, Checker()->GlobalBuiltinETSStringType()->AssemblerName()); BranchIfTrue(node, isString); Sa().Emit(node, 1); @@ -1563,6 +1575,7 @@ template void ETSGen::ResolveConditionalResult(const ir::AstNode *node, [[maybe_unused]] Label *ifFalse) { auto type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); #ifdef PANDA_WITH_ETS if (type->IsETSReferenceType()) { VReg valReg = AllocReg(); @@ -1625,6 +1638,7 @@ template void ETSGen::BranchConditional(const ir::AstNode *node, Label *endLabel) { auto type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSReferenceType()) { VReg valReg = AllocReg(); StoreAccumulator(node, valReg); @@ -1643,6 +1657,7 @@ void ETSGen::BranchConditional(const ir::AstNode *node, Label *endLabel) void ETSGen::ConditionalFloat(const ir::AstNode *node) { auto type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); VReg tmpReg = AllocReg(); VReg isNaNReg = AllocReg(); @@ -1682,6 +1697,7 @@ void ETSGen::BranchConditionalIfTrue(const ir::AstNode *node, Label *endLabel) void ETSGen::BranchIfNullish(const ir::AstNode *node, Label *ifNullish) { auto *const type = GetAccumulatorType(); + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSVoidType()) { // NOTE(): #19701 need void refactoring @@ -1724,6 +1740,7 @@ void ETSGen::BranchIfNotNullish(const ir::AstNode *node, Label *ifNotNullish) void ETSGen::AssumeNonNullish(const ir::AstNode *node, checker::Type const *targetType) { auto const *nullishType = GetAccumulatorType(); + ES2PANDA_ASSERT(nullishType != nullptr); if (nullishType->PossiblyETSNull()) { // clear 'null' dataflow EmitCheckCast(node, ToAssemblerType(targetType)); @@ -1904,6 +1921,7 @@ void ETSGen::HandleDefinitelyNullishEquality(const ir::AstNode *node, VReg lhs, } else { auto *checker = const_cast(Checker()); auto ltype = checker->GetNonConstantType(const_cast(GetVRegType(lhs))); + ES2PANDA_ASSERT(ltype != nullptr); LoadAccumulator(node, ltype->DefinitelyETSNullish() ? rhs : lhs); BranchIfNotNullish(node, ifFalse); } @@ -1940,6 +1958,7 @@ static std::optional> SelectL { auto alhs = checker->GetApparentType(checker->GetNonNullishType(lhs)); auto arhs = checker->GetApparentType(checker->GetNonNullishType(rhs)); + ES2PANDA_ASSERT(alhs != nullptr && arhs != nullptr); alhs = alhs->IsETSStringType() ? checker->GlobalBuiltinETSStringType() : alhs; arhs = arhs->IsETSStringType() ? checker->GlobalBuiltinETSStringType() : arhs; if (!alhs->IsETSObjectType() || !arhs->IsETSObjectType()) { @@ -2014,6 +2033,7 @@ void ETSGen::RefEqualityLoose(const ir::AstNode *node, VReg lhs, VReg rhs, Label auto *checker = const_cast(Checker()); auto ltype = checker->GetNonConstantType(const_cast(GetVRegType(lhs))); auto rtype = checker->GetNonConstantType(const_cast(GetVRegType(rhs))); + ES2PANDA_ASSERT(ltype != nullptr && rtype != nullptr); if (ltype->DefinitelyETSNullish() || rtype->DefinitelyETSNullish()) { HandleDefinitelyNullishEquality(node, lhs, rhs, ifFalse); } else if (auto spec = SelectLooseObjComparator( // try to select specific type @@ -2177,6 +2197,7 @@ void ETSGen::Unary(const ir::AstNode *node, lexer::TokenType op) void ETSGen::UnaryMinus(const ir::AstNode *node) { + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); if (GetAccumulatorType()->IsETSBigIntType()) { const VReg value = AllocReg(); StoreAccumulator(node, value); @@ -2212,6 +2233,7 @@ void ETSGen::UnaryMinus(const ir::AstNode *node) void ETSGen::UnaryTilde(const ir::AstNode *node) { + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); if (GetAccumulatorType()->IsETSBigIntType()) { const VReg value = AllocReg(); StoreAccumulator(node, value); @@ -2297,6 +2319,7 @@ void ETSGen::StringBuilderAppend(const ir::AstNode *node, VReg builder) signature = Signatures::BUILTIN_STRING_BUILDER_APPEND_BUILTIN_STRING; } + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); if (GetAccumulatorType()->IsETSReferenceType() && !GetAccumulatorType()->IsETSStringType()) { if (GetAccumulatorType()->PossiblyETSUndefined()) { Label *ifUndefined = AllocLabel(); @@ -2449,6 +2472,7 @@ void ETSGen::LoadResizableArrayLength(const ir::AstNode *node) void ETSGen::LoadResizableArrayElement(const ir::AstNode *node, const VReg arrObj, const VReg arrIndex) { auto *vRegType = GetVRegType(arrObj); + ES2PANDA_ASSERT(vRegType != nullptr); auto *elementType = vRegType->AsETSResizableArrayType()->ElementType(); Ra().Emit(node, Signatures::BUILTIN_ARRAY_GET_ELEMENT, arrObj, arrIndex); SetAccumulatorType(elementType); @@ -2462,6 +2486,7 @@ void ETSGen::LoadArrayLength(const ir::AstNode *node, VReg arrayReg) void ETSGen::LoadArrayElement(const ir::AstNode *node, VReg objectReg) { + ES2PANDA_ASSERT(GetVRegType(objectReg) != nullptr); auto *elementType = GetVRegType(objectReg)->AsETSArrayType()->ElementType(); if (elementType->IsETSReferenceType()) { Ra().Emit(node, objectReg); @@ -2558,7 +2583,7 @@ util::StringView ETSGen::GetTupleMemberNameForIndex(const std::size_t index) con void ETSGen::LoadTupleElement(const ir::AstNode *node, VReg objectReg, const checker::Type *elementType, std::size_t index) { - ES2PANDA_ASSERT(GetVRegType(objectReg)->IsETSTupleType()); + ES2PANDA_ASSERT(GetVRegType(objectReg) != nullptr && GetVRegType(objectReg)->IsETSTupleType()); const auto propName = FormClassPropReference(GetVRegType(objectReg)->AsETSTupleType()->GetWrapperType(), GetTupleMemberNameForIndex(index)); @@ -2570,7 +2595,7 @@ void ETSGen::LoadTupleElement(const ir::AstNode *node, VReg objectReg, const che void ETSGen::StoreTupleElement(const ir::AstNode *node, VReg objectReg, const checker::Type *elementType, std::size_t index) { - ES2PANDA_ASSERT(GetVRegType(objectReg)->IsETSTupleType()); + ES2PANDA_ASSERT(GetVRegType(objectReg) != nullptr && GetVRegType(objectReg)->IsETSTupleType()); const auto *const tupleType = GetVRegType(objectReg)->AsETSTupleType(); SetVRegType(objectReg, tupleType->GetWrapperType()); @@ -2708,7 +2733,7 @@ bool ETSGen::ExtendWithFinalizer(ir::AstNode const *node, const ir::AstNode *ori util::StringView ETSGen::ToAssemblerType(const es2panda::checker::Type *type) const { - ES2PANDA_ASSERT(type->IsETSReferenceType()); + ES2PANDA_ASSERT(type != nullptr && type->IsETSReferenceType()); std::stringstream ss; type->ToAssemblerTypeWithRank(ss); diff --git a/ets2panda/compiler/core/ETSGen.h b/ets2panda/compiler/core/ETSGen.h index 6707dcca73..1fd7c62350 100644 --- a/ets2panda/compiler/core/ETSGen.h +++ b/ets2panda/compiler/core/ETSGen.h @@ -298,7 +298,7 @@ public: bool IsDevirtualizedSignature(const checker::Signature *signature) { - ES2PANDA_ASSERT(!signature->HasSignatureFlag(checker::SignatureFlags::STATIC)); + ES2PANDA_ASSERT(signature != nullptr && !signature->HasSignatureFlag(checker::SignatureFlags::STATIC)); return signature->HasSignatureFlag(checker::SignatureFlags::FINAL | checker::SignatureFlags::PRIVATE | checker::SignatureFlags::CONSTRUCTOR); } @@ -456,6 +456,7 @@ public: if (isEtsPrimitive) { // NOTE: SzD. LoadStaticProperty if ETS stdlib has static TYPE constants otherwise fallback to LdaType } else { + ES2PANDA_ASSERT(GetAccumulatorType() != nullptr); auto classRef = GetAccumulatorType()->AsETSObjectType()->AssemblerName(); Sa().Emit(node, classRef); } diff --git a/ets2panda/compiler/core/function.cpp b/ets2panda/compiler/core/function.cpp index 685ed2c89e..e5c05ca78b 100644 --- a/ets2panda/compiler/core/function.cpp +++ b/ets2panda/compiler/core/function.cpp @@ -128,6 +128,7 @@ static void CompileFunctionParameterDeclaration(PandaGen *pg, const ir::ScriptFu void Function::LoadClassContexts(const ir::AstNode *node, PandaGen *pg, VReg ctor, const util::StringView &name) { auto *classDef = util::Helpers::GetContainingClassDefinition(node); + ES2PANDA_ASSERT(classDef != nullptr); do { auto res = pg->Scope()->Find(classDef->InternalName()); diff --git a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp index c5a51475ae..780c1346a8 100644 --- a/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp +++ b/ets2panda/compiler/lowering/scopesInit/scopesInitPhase.cpp @@ -582,6 +582,7 @@ void ScopeInitTyped::VisitTSModuleDeclaration(ir::TSModuleDeclaration *moduleDec if (!moduleDecl->IsExternalOrAmbient()) { auto name = moduleDecl->Name()->AsIdentifier()->Name(); auto *decl = AddOrGetDecl(VarBinder(), name, moduleDecl, moduleDecl->Name()->Start(), name); + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(moduleDecl); } auto localCtx = LexicalScopeCreateOrEnter(VarBinder(), moduleDecl); @@ -643,6 +644,7 @@ void ScopeInitTyped::VisitTSInterfaceDeclaration(ir::TSInterfaceDeclaration *int auto localScope = LexicalScopeCreateOrEnter(VarBinder(), interfDecl); auto *identDecl = AddOrGetDecl(VarBinder(), ident->Name(), interfDecl, ident->Start(), ident->Name()); + ES2PANDA_ASSERT(identDecl != nullptr); identDecl->BindNode(interfDecl); BindScopeNode(localScope.GetScope(), interfDecl); @@ -786,6 +788,7 @@ void InitScopesPhaseTs::CreateFuncDecl(ir::ScriptFunction *func) decl = currentDecl->AsFunctionDecl(); } + ES2PANDA_ASSERT(decl != nullptr); decl->Add(func); } @@ -972,13 +975,14 @@ void AddOverload(ir::MethodDefinition *overload, varbinder::Variable *variable) { auto *currentNode = variable->Declaration()->Node(); currentNode->AsMethodDefinition()->AddOverload(overload); + ES2PANDA_ASSERT(overload->Id() != nullptr); overload->Id()->SetVariable(variable); overload->SetParent(currentNode); } void InitScopesPhaseETS::DeclareClassMethod(ir::MethodDefinition *method) { - ES2PANDA_ASSERT(VarBinder()->GetScope()->IsClassScope()); + ES2PANDA_ASSERT(VarBinder()->GetScope()->IsClassScope() && method->AsMethodDefinition()->Function() != nullptr); if ((method->AsMethodDefinition()->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) != 0) { return; @@ -1034,7 +1038,8 @@ void InitScopesPhaseETS::MaybeAddOverload(ir::MethodDefinition *method, ir::Iden if (methodName->Name().Is(compiler::Signatures::MAIN) && clsScope->Parent()->IsGlobalScope()) { LogDiagnostic(diagnostic::OVERLOADED_MAIN, methodName->Start()); } - ES2PANDA_ASSERT((method->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); + ES2PANDA_ASSERT(method->Function() != nullptr && + (method->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); AddOverload(method, found); method->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); @@ -1198,6 +1203,7 @@ void InitScopesPhaseETS::VisitTSEnumMember(ir::TSEnumMember *enumMember) void InitScopesPhaseETS::VisitMethodDefinition(ir::MethodDefinition *method) { + ES2PANDA_ASSERT(method->Function() != nullptr); if (method->Function()->Scope() != nullptr) { return; } diff --git a/ets2panda/util/doubleLinkedList.h b/ets2panda/util/doubleLinkedList.h index a4d5a5a919..f2289bc185 100644 --- a/ets2panda/util/doubleLinkedList.h +++ b/ets2panda/util/doubleLinkedList.h @@ -54,6 +54,7 @@ public: Item *Append(const T &data) { auto item = allocator_->New(); + ES2PANDA_ASSERT(item != nullptr); item->data = data; Append(item); return item; @@ -77,6 +78,7 @@ public: Item *Prepend(const T &data) { auto item = allocator_->New(); + ES2PANDA_ASSERT(item != nullptr); item->data = data; Prepend(item); return item; @@ -100,6 +102,7 @@ public: Item *Insert(Item *after, const T &data) { auto item = allocator_->New(); + ES2PANDA_ASSERT(item != nullptr); item->data = data; Insert(after, item); return item; diff --git a/ets2panda/util/generateBin.cpp b/ets2panda/util/generateBin.cpp index 442bd41bc4..134b2c9511 100644 --- a/ets2panda/util/generateBin.cpp +++ b/ets2panda/util/generateBin.cpp @@ -83,6 +83,7 @@ static int GenerateProgramImpl(ark::pandasm::Program *prog, const util::Options std::cout << "Panda file size statistic:" << std::endl; constexpr std::array INFO_STATS = {"instructions_number", "codesize"}; + ES2PANDA_ASSERT(statp != nullptr); auto &stat = *statp; for (const auto &[name, size] : stat) { if (find(INFO_STATS.begin(), INFO_STATS.end(), name) != INFO_STATS.end()) { diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index 9bde843fb2..acc599db41 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -820,6 +820,7 @@ bool Helpers::IsAsyncMethod(ir::AstNode const *node) return false; } auto *method = node->AsMethodDefinition(); + ES2PANDA_ASSERT(method->Function() != nullptr); return method->Function()->IsAsyncFunc() && !method->Function()->IsProxy(); } diff --git a/ets2panda/util/options.cpp b/ets2panda/util/options.cpp index f3e1ea181f..e2818c61a2 100644 --- a/ets2panda/util/options.cpp +++ b/ets2panda/util/options.cpp @@ -303,6 +303,7 @@ void Options::InitializeWarnings() {"subset_aware", {ETSWarnings::SUBSET_AWARE_FIRST, ETSWarnings::SUBSET_AWARE_LAST}}, {"subset_unaware", {ETSWarnings::SUBSET_UNAWARE_FIRST, ETSWarnings::SUBSET_UNAWARE_LAST}}}; const auto setWarningRange = [&warningSet, v](size_t first, size_t last) { + ES2PANDA_ASSERT(last < ETSWarnings::COUNT); for (size_t i = first; i <= last; i++) { warningSet[i] = v; } diff --git a/ets2panda/util/path.cpp b/ets2panda/util/path.cpp index 995424b524..ad902018c6 100644 --- a/ets2panda/util/path.cpp +++ b/ets2panda/util/path.cpp @@ -75,7 +75,7 @@ void Path::InitializeFileName() } } - int extensionPosition = fileNameWithExtension_.Mutf8().find_last_of('.'); + size_t extensionPosition = fileNameWithExtension_.Mutf8().find_last_of('.'); fileName_ = fileNameWithExtension_.Substr(0, extensionPosition); } @@ -85,7 +85,7 @@ void Path::InitializeFileNameWithExtension() return; } - int position = path_.Mutf8().find_last_of(PATH_DELIMITER); + size_t position = path_.Mutf8().find_last_of(PATH_DELIMITER); fileNameWithExtension_ = path_.Substr(position + 1, path_.Length()); } @@ -114,7 +114,7 @@ void Path::InitializeAbsoluteParentFolder() return; } - int position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER); + size_t position = absolutePath_.Mutf8().find_last_of(PATH_DELIMITER); absoluteParentFolder_ = absolutePath_.Substr(0, position); } @@ -125,7 +125,7 @@ void Path::InitializeParentFolder() return; } - int position = path_.Mutf8().find_last_of(PATH_DELIMITER); + size_t position = path_.Mutf8().find_last_of(PATH_DELIMITER); parentFolder_ = path_.Substr(0, position); } diff --git a/ets2panda/util/ustring.h b/ets2panda/util/ustring.h index be6a745d60..b9106cc62b 100644 --- a/ets2panda/util/ustring.h +++ b/ets2panda/util/ustring.h @@ -202,6 +202,7 @@ public: inline void Reset(size_t offset) { + ES2PANDA_ASSERT(sv_.begin() + offset <= sv_.end()); iter_ = sv_.begin() + offset; } @@ -360,6 +361,7 @@ private: void Alloc() { str_ = allocator_->New(allocator_->Adapter()); + ES2PANDA_ASSERT(str_ != nullptr); } protected: @@ -481,6 +483,7 @@ std::string StringView::EscapeSymbol() const template void StringView::Utf8Encode(T *str, char32_t cu) { + ES2PANDA_ASSERT(str != nullptr); if (cu < Constants::UTF8_1BYTE_LIMIT) { str->push_back(static_cast(cu)); } else if (cu < Constants::UTF8_2BYTE_LIMIT) { diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index ce4d9475a3..f59a8972b7 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -91,6 +91,7 @@ static void CreateDummyVariable(ETSBinder *varBinder, ir::Identifier *ident) void ETSBinder::LookupTypeReference(ir::Identifier *ident) { + ES2PANDA_ASSERT(ident != nullptr); if (ident->Variable() != nullptr && ident->Variable()->Declaration()->Node() == ident) { return; } @@ -237,6 +238,7 @@ void ETSBinder::LookupIdentReference(ir::Identifier *ident) if (res.level != 0) { ES2PANDA_ASSERT(res.variable != nullptr); + ES2PANDA_ASSERT(GetScope()->EnclosingVariableScope() != nullptr); auto *outerFunction = GetScope()->EnclosingVariableScope()->Node(); if ((!outerFunction->IsScriptFunction() || !outerFunction->AsScriptFunction()->IsArrow()) && @@ -339,6 +341,7 @@ void ETSBinder::ResolveInterfaceDeclaration(ir::TSInterfaceDeclaration *decl) ResolveReference(stmt); + ES2PANDA_ASSERT(stmt->AsClassProperty()->Id() != nullptr); auto fieldVar = ResolvePropertyReference(stmt->AsClassProperty(), decl->Scope()->AsClassScope()) ->FindLocal(stmt->AsClassProperty()->Id()->Name(), varbinder::ResolveBindingOptions::BINDINGS); @@ -372,6 +375,7 @@ void ETSBinder::BuildMethodDefinition(ir::MethodDefinition *methodDef) methodDef->BaseOverloadMethod()->GetTopStatement() != methodDef->GetTopStatement()) { return; } + ES2PANDA_ASSERT(methodDef->Function() != nullptr); if (methodDef->Function()->TypeParams() != nullptr) { auto scopeCtx = LexicalScope::Enter(this, methodDef->Function()->TypeParams()->Scope()); ResolveReferences(methodDef->Function()->TypeParams()); @@ -429,6 +433,7 @@ void ETSBinder::ResolveMethodDefinition(ir::MethodDefinition *methodDef) } auto *thisParam = AddMandatoryParam(MANDATORY_PARAM_THIS); + ES2PANDA_ASSERT(thisParam != nullptr); thisParam->Declaration()->BindNode(thisParam_); } @@ -493,6 +498,7 @@ void ETSBinder::BuildClassDefinitionImpl(ir::ClassDefinition *classDef) auto *const prop = stmt->AsClassProperty(); auto fieldScope = ResolvePropertyReference(prop, classDef->Scope()->AsClassScope()); + ES2PANDA_ASSERT(prop->Id() != nullptr); auto fieldName = prop->Id()->Name(); if (auto fieldVar = fieldScope->FindLocal(fieldName, varbinder::ResolveBindingOptions::BINDINGS); fieldVar != nullptr) { @@ -527,6 +533,7 @@ void ETSBinder::AddFunctionThisParam(ir::ScriptFunction *func) { auto paramScopeCtx = LexicalScope::Enter(this, func->Scope()->ParamScope()); auto *thisParam = AddMandatoryParam(MANDATORY_PARAM_THIS); + ES2PANDA_ASSERT(thisParam != nullptr); thisParam->Declaration()->BindNode(thisParam_); } @@ -538,7 +545,7 @@ void ETSBinder::AddDynamicImport(ir::ETSImportDeclaration *import) void ETSBinder::BuildProxyMethod(ir::ScriptFunction *func, const util::StringView &containingClassName, bool isExternal) { - ES2PANDA_ASSERT(!containingClassName.Empty()); + ES2PANDA_ASSERT(!containingClassName.Empty() && func != nullptr); func->Scope()->BindName(containingClassName); if (!func->IsAsyncFunc() && !isExternal) { @@ -587,6 +594,7 @@ void AddOverloadFlag(ArenaAllocator *allocator, bool isStdLib, varbinder::Variab return; } + ES2PANDA_ASSERT(method->Function() != nullptr); if (!method->Overloads().empty() && !method->HasOverload(currentNode)) { method->AddOverload(currentNode); currentNode->Function()->Id()->SetVariable(importedVar); @@ -1469,6 +1477,7 @@ void ETSBinder::ValidateReexportDeclaration(ir::ETSReExportDeclaration *decl) bool ETSBinder::ImportGlobalPropertiesForNotDefaultedExports(varbinder::Variable *var, const util::StringView &name, const ir::ClassElement *classElement) { + ES2PANDA_ASSERT(var != nullptr); if (var->Declaration()->Node()->IsDefaultExported()) { return false; } @@ -1509,7 +1518,7 @@ void ETSBinder::ImportGlobalProperties(const ir::ClassDefinition *const classDef continue; } - ES2PANDA_ASSERT(classElement->IsStatic()); + ES2PANDA_ASSERT(classElement->IsStatic() && classElement->Id() != nullptr); const auto &name = classElement->Id()->Name(); auto *const var = scopeCtx.GetScope()->FindLocal(name, ResolveBindingOptions::ALL); ES2PANDA_ASSERT(var != nullptr); diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f6888b5055..4b20637e66 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -432,6 +432,7 @@ Variable *ParamScope::AddParameter(ArenaAllocator *allocator, Decl *newDecl, Var ES2PANDA_ASSERT(newDecl->IsParameterDecl()); auto *param = allocator->New(newDecl, flags); + ES2PANDA_ASSERT(param != nullptr); param->SetScope(this); params_.emplace_back(param); @@ -495,13 +496,12 @@ Variable *AnnotationParamScope::AddBinding([[maybe_unused]] ArenaAllocator *allo [[maybe_unused]] ScriptExtension extension) { auto *ident = newDecl->Node()->AsClassProperty()->Id(); + ES2PANDA_ASSERT(ident != nullptr); auto annoVar = allocator->New(newDecl, VariableFlags::PROPERTY); auto var = InsertBinding(ident->Name(), annoVar).first->second; if (var != nullptr) { var->SetScope(this); - if (ident != nullptr) { - ident->SetVariable(var); - } + ident->SetVariable(var); } return var; } @@ -721,6 +721,7 @@ void ModuleScope::AddImportDecl(ir::ImportDeclaration *importDecl, ImportDeclLis void ModuleScope::AddExportDecl(ir::AstNode *exportDecl, ExportDecl *decl) { + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(exportDecl); ArenaVector decls(allocator_->Adapter()); @@ -750,6 +751,7 @@ Variable *ModuleScope::AddImport(ArenaAllocator *allocator, Variable *currentVar } auto *variable = allocator->New(newDecl, VariableFlags::NONE); + ES2PANDA_ASSERT(variable != nullptr); variable->ExoticName() = newDecl->AsImportDecl()->ImportName(); InsertBinding(newDecl->Name(), variable); return variable; @@ -1010,6 +1012,7 @@ void LoopDeclarationScope::ConvertToVariableScope(ArenaAllocator *allocator) if (loopType_ == ScopeType::LOOP_DECL) { auto *parentVarScope = Parent()->EnclosingVariableScope(); + ES2PANDA_ASSERT(parentVarScope != nullptr); slotIndex_ = std::max(slotIndex_, parentVarScope->LexicalSlots()); evalBindings_ = parentVarScope->EvalBindings(); initScope_ = allocator->New(allocator, Parent()); -- Gitee From aa4aabe7eefacede544daf7188f5c3157ead49f3 Mon Sep 17 00:00:00 2001 From: Tatiana Titova Date: Wed, 2 Jul 2025 11:25:43 +0300 Subject: [PATCH 012/107] Add tests #26773 #26740 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJH76 Signed-off-by: Tatiana Titova --- .../compiler/ets/parameter_anonymous_type.ets | 23 +++++++++++++ .../test/ast/compiler/ets/spread_record.ets | 34 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets create mode 100644 ets2panda/test/ast/compiler/ets/spread_record.ets diff --git a/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets b/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets new file mode 100644 index 0000000000..a84669385c --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/parameter_anonymous_type.ets @@ -0,0 +1,23 @@ +/* + * 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. + */ + +const _innerFunc = (arg: { x: number } | undefined): number => { + if (arg === undefined) { + return 12; + } + return arg.x; +}; + +/* @@? 16:26 Error SyntaxError: Invalid Type. */ diff --git a/ets2panda/test/ast/compiler/ets/spread_record.ets b/ets2panda/test/ast/compiler/ets/spread_record.ets new file mode 100644 index 0000000000..ec7aa3a9dc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/spread_record.ets @@ -0,0 +1,34 @@ +/* + * 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. + */ + +let r1: Record = { 'one': '1' } +console.log(...r1) // crash - Issue #26773 +let r2: Record = { 'two': '2' } +let r3: Record = { ...r1, ...r2 } +console.log(...r3) // crash - Issue #26773 + + +/* @@? 17:1 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 17:1 Error TypeError: No matching call signature for log(...r1) */ +/* @@? 17:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ +/* @@? 17:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ +/* @@? 17:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ +/* @@? 17:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ +/* @@? 20:1 Error TypeError: No matching call signature for log(...r3) */ +/* @@? 20:1 Error TypeError: Expected 0 arguments, got 1. */ +/* @@? 20:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ +/* @@? 20:13 Error TypeError: Type 'Record' is not compatible with rest parameter type 'Array' at index 1 */ +/* @@? 20:13 Error TypeError: Spread expression can be applied only to array or tuple type, but 'Record' is provided */ +/* @@? 20:13 Error TypeError: Spread argument cannot be passed for ordinary parameter. */ -- Gitee From c0147f1742468c2dfa338b6c4867364e33c73a17 Mon Sep 17 00:00:00 2001 From: dongchao Date: Fri, 30 May 2025 10:27:56 +0800 Subject: [PATCH 013/107] Cancel detection of unused tools when enableDecl Issue: https://gitee.com/openharmony/interface_sdk-js/issues/ICHX7T Signed-off-by: dongchao Change-Id: Iafd28c3657b7882c726d64b2e790df4b036fc29f --- ets2panda/driver/build_system/src/build/base_mode.ts | 10 ++++------ .../driver/build_system/src/build/declgen_worker.ts | 11 ++++++----- .../build_system/src/init/process_build_config.ts | 4 ++-- ets2panda/driver/build_system/src/types.ts | 1 + 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 93a3e9b220..e6de447af6 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -106,6 +106,7 @@ export abstract class BaseMode { public hasCleanWorker: boolean; public byteCodeHar: boolean; public es2pandaMode: number; + public skipDeclCheck: boolean; constructor(buildConfig: BuildConfig) { this.buildConfig = buildConfig; @@ -142,6 +143,7 @@ export abstract class BaseMode { this.hasCleanWorker = false; this.byteCodeHar = buildConfig.byteCodeHar as boolean; this.es2pandaMode = buildConfig?.es2pandaMode ?? 0; + this.skipDeclCheck = buildConfig?.skipDeclCheck as boolean ?? true; } public declgen(fileInfo: CompileFileInfo): void { @@ -174,13 +176,13 @@ export abstract class BaseMode { arktsGlobal.compilerContext = arkts.Context.createFromString(source); PluginDriver.getInstance().getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, true); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, this.skipDeclCheck); let ast = arkts.EtsScript.fromContext(); PluginDriver.getInstance().getPluginContext().setArkTSAst(ast); PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, true); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, this.skipDeclCheck); ast = arkts.EtsScript.fromContext(); PluginDriver.getInstance().getPluginContext().setArkTSAst(ast); @@ -693,10 +695,6 @@ export abstract class BaseMode { protected collectCompileFiles(): void { this.entryFiles.forEach((file: string) => { - // Skip the declaration files when compiling abc - if (file.endsWith(DECL_ETS_SUFFIX)) { - return; - } for (const [packageName, moduleInfo] of this.moduleInfos) { const relativePath = path.relative(moduleInfo.moduleRootPath, file); if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) { diff --git a/ets2panda/driver/build_system/src/build/declgen_worker.ts b/ets2panda/driver/build_system/src/build/declgen_worker.ts index 872eb49db1..5a32a7f000 100644 --- a/ets2panda/driver/build_system/src/build/declgen_worker.ts +++ b/ets2panda/driver/build_system/src/build/declgen_worker.ts @@ -18,7 +18,7 @@ import { BuildConfig } from '../types'; import { Logger } from '../logger'; import * as fs from 'fs'; import * as path from 'path'; -import { changeFileExtension, ensurePathExists } from '../utils'; +import { changeDeclgenFileExtension, ensurePathExists } from '../utils'; import { DECL_ETS_SUFFIX, TS_SUFFIX, @@ -56,13 +56,13 @@ process.on('message', (message: { moduleInfo.packageName, filePathFromModuleRoot ); - declEtsOutputPath = changeFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX); + declEtsOutputPath = changeDeclgenFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX); let etsOutputPath: string = path.join( moduleInfo.declgenBridgeCodePath as string, moduleInfo.packageName, filePathFromModuleRoot ); - etsOutputPath = changeFileExtension(etsOutputPath, TS_SUFFIX); + etsOutputPath = changeDeclgenFileExtension(etsOutputPath, TS_SUFFIX); ensurePathExists(declEtsOutputPath); ensurePathExists(etsOutputPath); @@ -78,14 +78,15 @@ process.on('message', (message: { ]).peer; arktsGlobal.compilerContext = arkts.Context.createFromString(source); pluginDriver.getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program); + const skipDeclCheck = buildConfig?.skipDeclCheck as boolean ?? true; - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, true); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, skipDeclCheck); let ast = arkts.EtsScript.fromContext(); pluginDriver.getPluginContext().setArkTSAst(ast); pluginDriver.runPluginHook(PluginHook.PARSED); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, true); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, skipDeclCheck); ast = arkts.EtsScript.fromContext(); pluginDriver.getPluginContext().setArkTSAst(ast); diff --git a/ets2panda/driver/build_system/src/init/process_build_config.ts b/ets2panda/driver/build_system/src/init/process_build_config.ts index 40285b662b..46727bff70 100644 --- a/ets2panda/driver/build_system/src/init/process_build_config.ts +++ b/ets2panda/driver/build_system/src/init/process_build_config.ts @@ -103,7 +103,7 @@ function initPlatformSpecificConfig(buildConfig: BuildConfig): void { buildConfig.dependencyAnalyzerPath = path.join(pandaSdkPath, 'bin', 'dependency_analyzer'); } - if (!fs.existsSync(buildConfig.abcLinkerPath as string)) { + if (!buildConfig.enableDeclgenEts2Ts && !fs.existsSync(buildConfig.abcLinkerPath as string)) { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_ARK_LINK_NOT_FOUND_FAIL, 'Ark_link not found in path.', @@ -113,7 +113,7 @@ function initPlatformSpecificConfig(buildConfig: BuildConfig): void { logger.printError(logData); } - if (!buildConfig.frameworkMode && !fs.existsSync(buildConfig.dependencyAnalyzerPath as string)) { + if (!buildConfig.frameworkMode && !buildConfig.enableDeclgenEts2Ts && !fs.existsSync(buildConfig.dependencyAnalyzerPath as string)) { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_Dependency_Analyzer_NOT_FOUND_FAIL, 'Dependency_analyzer not found in path.', diff --git a/ets2panda/driver/build_system/src/types.ts b/ets2panda/driver/build_system/src/types.ts index d3012e4096..b6012b37ce 100644 --- a/ets2panda/driver/build_system/src/types.ts +++ b/ets2panda/driver/build_system/src/types.ts @@ -164,6 +164,7 @@ export interface DeclgenConfig { declgenV1OutPath?: string; declgenV2OutPath?: string; declgenBridgeCodePath?: string; + skipDeclCheck?: boolean; } export interface LoggerConfig { -- Gitee From 13aa2c168b7313c183e8db1dba6d76a44e0ee7e5 Mon Sep 17 00:00:00 2001 From: Maxim Bolshov Date: Wed, 2 Jul 2025 15:54:04 +0300 Subject: [PATCH 014/107] Minor utils/plugin refactoring * Add missing assert * Add missing static_cast Issue: #ICJK24 Testing: ninja ets_tests Signed-off-by: Maxim Bolshov --- ets2panda/compiler/lowering/util.cpp | 1 + ets2panda/public/es2panda_lib.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ets2panda/compiler/lowering/util.cpp b/ets2panda/compiler/lowering/util.cpp index a175fe9007..865e9d1827 100644 --- a/ets2panda/compiler/lowering/util.cpp +++ b/ets2panda/compiler/lowering/util.cpp @@ -64,6 +64,7 @@ util::UString GenName(ArenaAllocator *const allocator) void SetSourceRangesRecursively(ir::AstNode *node, const lexer::SourceRange &range) { + ES2PANDA_ASSERT(node != nullptr); node->SetRange(range); node->IterateRecursively([](ir::AstNode *n) { n->SetRange(n->Parent()->Range()); }); } diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 3935c32f7d..9fa90ef099 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -130,7 +130,7 @@ __attribute__((unused)) es2panda_variantDoubleCharArrayBool EnumMemberResultToEs // NOLINTBEGIN(cppcoreguidelines-pro-type-union-access) // NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-simplify-subscript-expr) es2panda_variantDoubleCharArrayBool es2panda_variant; - es2panda_variant.index = variant.index(); + es2panda_variant.index = static_cast(variant.index()); switch (es2panda_variant.index) { case es2panda_variantIndex::CAPI_DOUBLE: es2panda_variant.variant.d = std::get(variant); -- Gitee From 5fac851a69fe1d9c59573f0139f12b3e3605441d Mon Sep 17 00:00:00 2001 From: Okolnov Evgeniy Date: Tue, 1 Jul 2025 11:56:09 +0300 Subject: [PATCH 015/107] Fix false `arkts-no-structural-typing` reports Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJ6VM Test scenarios: new tests added to the linter Signed-off-by: Okolnov Evgeniy --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 287 +++----------- ets2panda/linter/src/lib/utils/TsUtils.ts | 10 + .../linter/test/main/structural_identity.ets | 27 +- .../main/structural_identity.ets.arkts2.json | 374 +----------------- .../test/main/structural_identity_2.ets | 45 +++ .../main/structural_identity_2.ets.args.json | 19 + .../structural_identity_2.ets.arkts2.json | 48 +++ .../test/main/structural_identity_2.ets.json | 17 + .../test/main/structural_identity_promise.ets | 35 ++ .../structural_identity_promise.ets.args.json | 19 + ...tructural_identity_promise.ets.arkts2.json | 17 + .../main/structural_identity_promise.ets.json | 17 + 12 files changed, 301 insertions(+), 614 deletions(-) create mode 100644 ets2panda/linter/test/main/structural_identity_2.ets create mode 100644 ets2panda/linter/test/main/structural_identity_2.ets.args.json create mode 100644 ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/structural_identity_2.ets.json create mode 100644 ets2panda/linter/test/main/structural_identity_promise.ets create mode 100644 ets2panda/linter/test/main/structural_identity_promise.ets.args.json create mode 100644 ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/structural_identity_promise.ets.json diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 0b7067a939..c5fb45224d 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -158,16 +158,6 @@ import { D_ETS, D_TS } from './utils/consts/TsSuffix'; import { arkTsBuiltInTypeName } from './utils/consts/ArkuiImportList'; import { ERROR_TASKPOOL_PROP_LIST } from './utils/consts/ErrorProp'; -interface InterfaceSymbolTypeResult { - propNames: string[]; - typeNames: string[]; - allProps: Map; -} -interface InterfaceSymbolTypePropertyNames { - propertyNames: string[]; - typeNames: string[]; -} - export class TypeScriptLinter extends BaseTypeScriptLinter { supportedStdCallApiChecker: SupportedStdCallApiChecker; @@ -2496,7 +2486,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleInvalidIdentifier(tsVarDecl); this.checkAssignmentNumericSemanticsly(tsVarDecl); this.checkTypeFromSdk(tsVarDecl.type); - this.handleNoStructuralTyping(tsVarDecl); this.handleObjectLiteralforUnionTypeInterop(tsVarDecl); this.handleObjectLiteralAssignmentToClass(tsVarDecl); this.handleObjectLiteralAssignment(tsVarDecl); @@ -2524,194 +2513,6 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private static extractUsedObjectType(tsVarDecl: ts.VariableDeclaration): InterfaceSymbolTypePropertyNames | null { - const result = { - propertyNames: [] as string[], - typeNames: [] as string[] - }; - - if (!this.isObjectLiteralWithProperties(tsVarDecl)) { - return null; - } - - this.processObjectLiteralProperties(tsVarDecl.initializer as ts.ObjectLiteralExpression, result); - return result.propertyNames.length > 0 ? result : null; - } - - private static isObjectLiteralWithProperties(tsVarDecl: ts.VariableDeclaration): boolean { - return ( - tsVarDecl.initializer !== undefined && - ts.isObjectLiteralExpression(tsVarDecl.initializer) && - tsVarDecl.initializer.properties.length > 0 - ); - } - - private static processObjectLiteralProperties( - objectLiteral: ts.ObjectLiteralExpression, - result: { propertyNames: string[]; typeNames: string[] } - ): void { - objectLiteral.properties.forEach((property) => { - if (!ts.isPropertyAssignment(property)) { - return; - } - - const propertyName = property.name.getText(); - result.propertyNames.push(propertyName); - - if (ts.isNewExpression(property.initializer)) { - const typeName = property.initializer.expression.getText(); - result.typeNames.push(typeName); - } - }); - } - - private interfaceSymbolType(tsVarDecl: ts.VariableDeclaration): InterfaceSymbolTypeResult | null { - if (!tsVarDecl.type) { - return null; - } - - const typeSymbol = this.getTypeSymbol(tsVarDecl); - if (!typeSymbol) { - return null; - } - - const interfaceType = this.getInterfaceType(tsVarDecl); - if (!interfaceType) { - return null; - } - - return this.collectInterfaceProperties(interfaceType, tsVarDecl); - } - - private getTypeSymbol(tsVarDecl: ts.VariableDeclaration): ts.Symbol | null { - const typeNode = ts.isTypeReferenceNode(tsVarDecl.type!) ? tsVarDecl.type.typeName : tsVarDecl.type; - return this.tsTypeChecker.getSymbolAtLocation(typeNode!) ?? null; - } - - private getInterfaceType(tsVarDecl: ts.VariableDeclaration): ts.InterfaceType | null { - const type = this.tsTypeChecker.getTypeAtLocation(tsVarDecl.type!); - return type && (type as ts.ObjectType).objectFlags & ts.ObjectFlags.Interface ? (type as ts.InterfaceType) : null; - } - - private collectInterfaceProperties( - interfaceType: ts.InterfaceType, - tsVarDecl: ts.VariableDeclaration - ): InterfaceSymbolTypeResult { - const result = { - propNames: [] as string[], - typeNames: [] as string[], - allProps: new Map() - }; - - this.collectPropertiesRecursive(interfaceType, result, tsVarDecl); - return result; - } - - private collectPropertiesRecursive( - type: ts.Type, - result: { - propNames: string[]; - typeNames: string[]; - allProps: Map; - }, - tsVarDecl: ts.VariableDeclaration - ): void { - type.getProperties().forEach((property) => { - this.collectProperty(property, result, tsVarDecl); - }); - - if ('getBaseTypes' in type) { - type.getBaseTypes()?.forEach((baseType) => { - this.collectPropertiesRecursive(baseType, result, tsVarDecl); - }); - } - } - - private collectProperty( - property: ts.Symbol, - result: { - propNames: string[]; - typeNames: string[]; - allProps: Map; - }, - tsVarDecl: ts.VariableDeclaration - ): void { - const propName = property.getName(); - const propType = this.tsTypeChecker.getTypeOfSymbolAtLocation( - property, - property.valueDeclaration || tsVarDecl.type! - ); - const typeString = this.tsTypeChecker.typeToString(propType); - - if (!result.allProps.has(propName)) { - result.propNames.push(propName); - result.typeNames.push(typeString); - result.allProps.set(propName, typeString); - } - } - - handleNoStructuralTyping(tsVarDecl: ts.VariableDeclaration): void { - const { interfaceInfo, actualUsage } = this.getTypeComparisonData(tsVarDecl); - if (!interfaceInfo || !actualUsage) { - return; - } - if (!this.options.arkts2) { - return; - } - const actualMap = TypeScriptLinter.createActualTypeMap(actualUsage); - const hasMismatch = TypeScriptLinter.checkTypeMismatches(interfaceInfo, actualMap); - - if (hasMismatch) { - this.incrementCounters(tsVarDecl, FaultID.StructuralIdentity); - } - } - - private getTypeComparisonData(tsVarDecl: ts.VariableDeclaration): { - interfaceInfo: { propNames: string[]; typeNames: string[]; allProps: Map } | null; - actualUsage: { - propertyNames: string[]; - typeNames: string[]; - } | null; - } { - return { - interfaceInfo: this.interfaceSymbolType(tsVarDecl), - actualUsage: TypeScriptLinter.extractUsedObjectType(tsVarDecl) - }; - } - - private static createActualTypeMap(actualUsage: { - propertyNames: string[]; - typeNames: string[]; - }): Map { - const actualMap = new Map(); - actualUsage.propertyNames.forEach((prop, index) => { - if (actualUsage.typeNames[index]) { - actualMap.set(prop, actualUsage.typeNames[index]); - } - }); - return actualMap; - } - - private static checkTypeMismatches( - interfaceInfo: { allProps: Map }, - actualMap: Map - ): boolean { - let hasMismatch = false; - - interfaceInfo.allProps.forEach((expectedType, prop) => { - if (!actualMap.has(prop)) { - return; - } - - const actualType = actualMap.get(prop)!; - if (expectedType !== actualType) { - hasMismatch = true; - } - }); - - return hasMismatch; - } - private handleDeclarationDestructuring(decl: ts.VariableDeclaration | ts.ParameterDeclaration): void { const faultId = ts.isVariableDeclaration(decl) ? FaultID.DestructuringDeclaration : FaultID.DestructuringParameter; if (ts.isObjectBindingPattern(decl.name)) { @@ -5327,22 +5128,27 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (this.tsUtils.isWrongSendableFunctionAssignment(targetType, exprType)) { this.incrementCounters(tsAsExpr, FaultID.SendableFunctionAsExpr); } + this.handleAsExprStructuralTyping(tsAsExpr, targetType, exprType); + this.handleAsExpressionImport(tsAsExpr); + this.handleNoTuplesArrays(node, targetType, exprType); + this.handleObjectLiteralAssignmentToClass(tsAsExpr); + this.handleArrayTypeImmutable(tsAsExpr, exprType, targetType); + this.handleNotsLikeSmartTypeOnAsExpression(tsAsExpr); + } + + private handleAsExprStructuralTyping(asExpr: ts.AsExpression, targetType: ts.Type, exprType: ts.Type): void { if ( this.options.arkts2 && - this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, tsAsExpr.expression, true) + this.tsUtils.needToDeduceStructuralIdentity(targetType, exprType, asExpr.expression, true) && + this.tsUtils.needToDeduceStructuralIdentity(exprType, targetType, asExpr.expression, true) ) { - if (this.isExemptedAsExpression(tsAsExpr)) { + if (this.isExemptedAsExpression(asExpr)) { return; } if (!this.tsUtils.isObject(exprType)) { - this.incrementCounters(node, FaultID.StructuralIdentity); + this.incrementCounters(asExpr, FaultID.StructuralIdentity); } } - this.handleAsExpressionImport(tsAsExpr); - this.handleNoTuplesArrays(node, targetType, exprType); - this.handleObjectLiteralAssignmentToClass(tsAsExpr); - this.handleArrayTypeImmutable(tsAsExpr, exprType, targetType); - this.handleNotsLikeSmartTypeOnAsExpression(tsAsExpr); } private isExemptedAsExpression(node: ts.AsExpression): boolean { @@ -6214,41 +6020,72 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { * only need to strictly match the type of filling the check again */ private checkAssignmentMatching( - field: ts.Node, + contextNode: ts.Node, lhsType: ts.Type, rhsExpr: ts.Expression, isNewStructuralCheck: boolean = false ): void { const rhsType = this.tsTypeChecker.getTypeAtLocation(rhsExpr); - this.handleNoTuplesArrays(field, lhsType, rhsType); - this.handleArrayTypeImmutable(field, lhsType, rhsType, rhsExpr); + this.handleNoTuplesArrays(contextNode, lhsType, rhsType); + this.handleArrayTypeImmutable(contextNode, lhsType, rhsType, rhsExpr); // check that 'sendable typeAlias' is assigned correctly if (this.tsUtils.isWrongSendableFunctionAssignment(lhsType, rhsType)) { - this.incrementCounters(field, FaultID.SendableFunctionAssignment); + this.incrementCounters(contextNode, FaultID.SendableFunctionAssignment); } const isStrict = this.tsUtils.needStrictMatchType(lhsType, rhsType); // 'isNewStructuralCheck' means that this assignment scenario was previously omitted, so only strict matches are checked now if (isNewStructuralCheck && !isStrict) { return; } + this.handleStructuralTyping(contextNode, lhsType, rhsType, rhsExpr, isStrict); + } + + private handleStructuralTyping( + contextNode: ts.Node, + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression, + isStrict: boolean + ): void { + if (TypeScriptLinter.isValidPromiseReturnedFromAsyncFunction(lhsType, rhsType, rhsExpr)) { + return; + } if (this.tsUtils.needToDeduceStructuralIdentity(lhsType, rhsType, rhsExpr, isStrict)) { - if (ts.isNewExpression(rhsExpr) && ts.isIdentifier(rhsExpr.expression) && rhsExpr.expression.text === 'Promise') { - const isReturnStatement = ts.isReturnStatement(rhsExpr.parent); - const enclosingFunction = ts.findAncestor(rhsExpr, ts.isFunctionLike); - const isAsyncFunction = - enclosingFunction && - (enclosingFunction.modifiers?.some((m) => { - return m.kind === ts.SyntaxKind.AsyncKeyword; - }) || - false); - if (isReturnStatement && isAsyncFunction) { - return; - } - } - this.incrementCounters(field, FaultID.StructuralIdentity); + this.incrementCounters(contextNode, FaultID.StructuralIdentity); } } + private static isValidPromiseReturnedFromAsyncFunction( + lhsType: ts.Type, + rhsType: ts.Type, + rhsExpr: ts.Expression + ): boolean { + + /* + * When resolving the contextual type for return expression in async function, the TS compiler + * infers 'PromiseLike' type instead of standard 'Promise' (see following link: + * https://github.com/microsoft/TypeScript/pull/27270). In this special case, we treat + * these two types as equal and only need to validate the type argument. + */ + + if (!ts.isReturnStatement(rhsExpr.parent)) { + return false; + } + const enclosingFunction = ts.findAncestor(rhsExpr, ts.isFunctionLike); + if (!TsUtils.hasModifier(enclosingFunction?.modifiers, ts.SyntaxKind.AsyncKeyword)) { + return false; + } + + const lhsPromiseLikeType = lhsType.isUnion() && lhsType.types.find(TsUtils.isStdPromiseLikeType); + if (!lhsPromiseLikeType || !TsUtils.isStdPromiseType(rhsType)) { + return false; + } + + const lhsTypeArg = TsUtils.isTypeReference(lhsPromiseLikeType) && lhsPromiseLikeType.typeArguments?.[0]; + const rhsTypeArg = TsUtils.isTypeReference(rhsType) && rhsType.typeArguments?.[0]; + return lhsTypeArg !== undefined && lhsTypeArg === rhsTypeArg; + } + private handleDecorator(node: ts.Node): void { this.handleExtendDecorator(node); this.handleEntryDecorator(node); diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index e164774602..db9e766033 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -3794,4 +3794,14 @@ export class TsUtils { } return typeNode.kind === ts.SyntaxKind.VoidKeyword; } + + static isStdPromiseType(type: ts.Type): boolean { + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'Promise' && isStdLibrarySymbol(sym); + } + + static isStdPromiseLikeType(type: ts.Type): boolean { + const sym = type.getSymbol(); + return !!sym && sym.getName() === 'PromiseLike' && isStdLibrarySymbol(sym); + } } diff --git a/ets2panda/linter/test/main/structural_identity.ets b/ets2panda/linter/test/main/structural_identity.ets index 406a7fee8e..48def20681 100644 --- a/ets2panda/linter/test/main/structural_identity.ets +++ b/ets2panda/linter/test/main/structural_identity.ets @@ -681,24 +681,17 @@ class MyObj3 { } interface goodPerson extends IPerson { - like: MyObj2, - like1: MyObj3 - } - - let lily:goodPerson = { - like: new MyObj1(), - name: 'Alice', - age: 30, - sayHello:()=> { - return new MyObj2() - } - } - - async function foo1(): Promise{ - - return new Promise(()=>{ + like: MyObj2, + like1: MyObj3 +} - }); +let lily: goodPerson = { + like: new MyObj1(), + name: 'Alice', + age: 30, + sayHello:()=> { + return new MyObj2() + } } function foo2(rule:Record){ diff --git a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json index 9c75437ef7..cadab9b537 100644 --- a/ets2panda/linter/test/main/structural_identity.ets.arkts2.json +++ b/ets2panda/linter/test/main/structural_identity.ets.arkts2.json @@ -84,16 +84,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 66, - "column": 13, - "endLine": 66, - "endColumn": 23, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 108, "column": 4, @@ -434,246 +424,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 244, - "column": 1, - "endLine": 244, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 245, - "column": 1, - "endLine": 245, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 246, - "column": 1, - "endLine": 246, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 247, - "column": 1, - "endLine": 247, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 248, - "column": 1, - "endLine": 248, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 249, - "column": 1, - "endLine": 249, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 250, - "column": 1, - "endLine": 250, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 251, - "column": 1, - "endLine": 251, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 252, - "column": 1, - "endLine": 252, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 253, - "column": 1, - "endLine": 253, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 254, - "column": 1, - "endLine": 254, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 255, - "column": 1, - "endLine": 255, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 281, - "column": 1, - "endLine": 281, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 282, - "column": 1, - "endLine": 282, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 283, - "column": 1, - "endLine": 283, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 284, - "column": 1, - "endLine": 284, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 285, - "column": 1, - "endLine": 285, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 286, - "column": 1, - "endLine": 286, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 287, - "column": 1, - "endLine": 287, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 288, - "column": 1, - "endLine": 288, - "endColumn": 16, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 289, - "column": 1, - "endLine": 289, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 290, - "column": 1, - "endLine": 290, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 291, - "column": 1, - "endLine": 291, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 292, - "column": 1, - "endLine": 292, - "endColumn": 17, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 319, "column": 15, @@ -784,86 +534,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 400, - "column": 3, - "endLine": 400, - "endColumn": 11, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 401, - "column": 3, - "endLine": 401, - "endColumn": 19, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 402, - "column": 3, - "endLine": 402, - "endColumn": 19, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 406, - "column": 3, - "endLine": 406, - "endColumn": 32, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 413, - "column": 3, - "endLine": 413, - "endColumn": 13, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 414, - "column": 3, - "endLine": 414, - "endColumn": 21, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 415, - "column": 3, - "endLine": 415, - "endColumn": 21, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 419, - "column": 3, - "endLine": 419, - "endColumn": 36, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 451, "column": 3, @@ -874,36 +544,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 452, - "column": 3, - "endLine": 452, - "endColumn": 20, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 453, - "column": 3, - "endLine": 453, - "endColumn": 15, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, - { - "line": 457, - "column": 3, - "endLine": 457, - "endColumn": 46, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 460, "column": 3, @@ -1654,16 +1294,6 @@ "rule": "Structural typing is not supported (arkts-no-structural-typing)", "severity": "ERROR" }, - { - "line": 688, - "column": 6, - "endLine": 695, - "endColumn": 3, - "problem": "StructuralIdentity", - "suggest": "", - "rule": "Structural typing is not supported (arkts-no-structural-typing)", - "severity": "ERROR" - }, { "line": 688, "column": 24, @@ -1676,9 +1306,9 @@ }, { "line": 691, - "column": 10, + "column": 8, "endLine": 691, - "endColumn": 12, + "endColumn": 10, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", diff --git a/ets2panda/linter/test/main/structural_identity_2.ets b/ets2panda/linter/test/main/structural_identity_2.ets new file mode 100644 index 0000000000..95729d873f --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets @@ -0,0 +1,45 @@ +/* + * 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 A {} +class B {} +class C extends A {} + +function test1(ab?: A | B) { + const a = ab as A ?? new A(); // No error in ArkTS 1.2 + const b = ab as B ?? new B(); // No error in ArkTS 1.2 +} + +function test2(): A | null { + return new B(); // Error in ArkTS 1.2 +} + +function test3(a: A): C | undefined { + return a ? a as C : undefined; // No error in ArkTS 1.2 +} + +function test4(): void { + console.log(new A() as B); // Error in ArkTS 1.2 + console.log(new B() as C); // Error in ArkTS 1.2 + console.log(new A() as C); // No error in ArkTS 1.2 + console.log(new C() as A); // No error in ArkTS 1.2 +} + +interface I { + a?: A; +} +let i: I = { + a: new A() // No error in ArkTS 1.2 +}; \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.args.json b/ets2panda/linter/test/main/structural_identity_2.ets.args.json new file mode 100644 index 0000000000..3ef4496a81 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json new file mode 100644 index 0000000000..822b392710 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.arkts2.json @@ -0,0 +1,48 @@ +{ + "copyright": [ + "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." + ], + "result": [ + { + "line": 26, + "column": 10, + "endLine": 26, + "endColumn": 17, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 15, + "endLine": 34, + "endColumn": 27, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 15, + "endLine": 35, + "endColumn": 27, + "problem": "StructuralIdentity", + "suggest": "", + "rule": "Structural typing is not supported (arkts-no-structural-typing)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_2.ets.json b/ets2panda/linter/test/main/structural_identity_2.ets.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets b/ets2panda/linter/test/main/structural_identity_promise.ets new file mode 100644 index 0000000000..e9fe68fd17 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets @@ -0,0 +1,35 @@ +/* + * 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 X {} + +async function foo(): Promise{ + return new Promise(() => { }); // No error in ArkTS 1.2 +} + +async function bar(): Promise{ + return new X(); // No error in ArkTS 1.2 +} + +class PromiseTest { + protected async foo(): Promise { + let arr: X[] = []; + return arr; + } + + public async bar(): Promise { + return this.foo(); // No error in ArkTS 1.2 + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.args.json b/ets2panda/linter/test/main/structural_identity_promise.ets.args.json new file mode 100644 index 0000000000..3ef4496a81 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "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." + ], + "mode": { + "arkts2": "" + } +} diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json b/ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets.arkts2.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/structural_identity_promise.ets.json b/ets2panda/linter/test/main/structural_identity_promise.ets.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/structural_identity_promise.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file -- Gitee From 25638872760b491db8466f335e5bbdb1fed2e70e Mon Sep 17 00:00:00 2001 From: xingshunxiang Date: Mon, 30 Jun 2025 18:54:08 +0800 Subject: [PATCH 016/107] Redef Builtin Class cause SegV Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIXY8?from=project-issue Description: Redef Builtin Class cause SegV Reason: In VarBinder, Redef Builtin class will Break the GlobalTypesHolder, because the Redef Builtin class will be inserted to bindingMaps, but with no builtin flag. Tests: ninja tests passed tests/tests-u-runner/runner.sh --ets-cts --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --ets-func-tests --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --astchecker --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --ets-runtime --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --parser --no-js --show-progress --build-dir x64.release --processes=all passed Signed-off-by: xingshunxiang --- .../compiler/ets/invalid_class_declare.ets | 20 +++++++++++++ ets2panda/varbinder/ETSBinder.cpp | 6 ++++ ets2panda/varbinder/scope.cpp | 30 +++++++++++++++++++ ets2panda/varbinder/scope.h | 2 ++ 4 files changed, 58 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/invalid_class_declare.ets diff --git a/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets b/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets new file mode 100644 index 0000000000..082a7347c6 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_class_declare.ets @@ -0,0 +1,20 @@ +/* + * 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 Integral {} +class Numeric {} + +/* @@? 1:3 Error TypeError: Class 'Integral' is already defined. */ +/* @@? 1:3 Error TypeError: Class 'Numeric' is already defined. */ diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index ce4d9475a3..6a6844bed1 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -643,6 +643,12 @@ void ETSBinder::ImportAllForeignBindings(const varbinder::Scope::VariableMap &gl InsertForeignBinding(bindingName, var); } + // redeclaration for builtin type, + // need to erase the redeclaration one and make sure the builtin types initialized successfully. + if (var->HasFlag(varbinder::VariableFlags::BUILTIN_TYPE)) { + TopScope()->CorrectForeignBinding(bindingName, var, variable); + } + ThrowRedeclarationError(import->Source()->Start(), var, variable, bindingName); } } diff --git a/ets2panda/varbinder/scope.cpp b/ets2panda/varbinder/scope.cpp index f6888b5055..027603c424 100644 --- a/ets2panda/varbinder/scope.cpp +++ b/ets2panda/varbinder/scope.cpp @@ -75,6 +75,27 @@ Variable *Scope::FindLocal(const util::StringView &name, ResolveBindingOptions o return res->second; } +bool Scope::CorrectForeignBinding(const util::StringView &name, Variable *builtinVar, Variable *redefinedVar) +{ + ES2PANDA_ASSERT(builtinVar != redefinedVar); + auto bindingTobeErase = bindings_.find(name); + if (bindingTobeErase == bindings_.end()) { + return false; + } + + Variable *varTobeErase = bindingTobeErase->second; + if (varTobeErase != redefinedVar) { + return false; + } + + auto declTobeErase = redefinedVar->Declaration(); + bindings_.erase(name); + auto it = std::find_if(decls_.begin(), decls_.end(), [&](auto *decl) { return decl == declTobeErase; }); + ES2PANDA_ASSERT(it != decls_.end()); + decls_.erase(it); + return Scope::InsertBinding(name, builtinVar).second; +} + Scope::InsertResult Scope::InsertBinding(const util::StringView &name, Variable *const var) { ES2PANDA_ASSERT(var != nullptr); @@ -633,6 +654,15 @@ Scope::InsertResult GlobalScope::InsertOrAssignForeignBinding(const util::String return GlobalScope::InsertImpl(name, var, InsertBindingFlags::FOREIGN | InsertBindingFlags::ASSIGN); } +bool GlobalScope::CorrectForeignBinding(const util::StringView &name, Variable *builtinVar, Variable *redefinedVar) +{ + const bool deleteRes = Scope::CorrectForeignBinding(name, builtinVar, redefinedVar); + if (deleteRes) { + foreignBindings_[name] = true; + } + return deleteRes; +} + Scope::InsertResult GlobalScope::InsertImpl(const util::StringView &name, Variable *const var, const InsertBindingFlags flags) { diff --git a/ets2panda/varbinder/scope.h b/ets2panda/varbinder/scope.h index d8701598bd..f816261a47 100644 --- a/ets2panda/varbinder/scope.h +++ b/ets2panda/varbinder/scope.h @@ -249,6 +249,7 @@ public: virtual InsertResult TryInsertBinding(const util::StringView &name, Variable *var); virtual void MergeBindings(VariableMap const &bindings); virtual VariableMap::size_type EraseBinding(const util::StringView &name); + virtual bool CorrectForeignBinding(const util::StringView &name, Variable *builtinVar, Variable *redefinedVar); [[nodiscard]] const VariableMap &Bindings() const noexcept { @@ -894,6 +895,7 @@ public: [[nodiscard]] bool IsForeignBinding(const util::StringView &name) const; InsertResult InsertDynamicBinding(const util::StringView &name, Variable *var); + bool CorrectForeignBinding(const util::StringView &name, Variable *builtinVar, Variable *redefinedVar) override; private: enum class InsertBindingFlags : uint8_t { NONE = 0, FOREIGN = 1U << 0U, DYNAMIC = 1U << 1U, ASSIGN = 1U << 2U }; -- Gitee From b8c213a3f98dd4089c9872f83e337a8069cc7413 Mon Sep 17 00:00:00 2001 From: Ocean Date: Wed, 2 Jul 2025 15:45:23 +0800 Subject: [PATCH 017/107] Support insert import stmt after 'use static' Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJGEV Reason: "use static" statement was introduced into ArkTS recently Description: insert import statement right after "use static" statement Signed-off-by: Ocean --- ets2panda/public/es2panda_lib.cpp | 10 +++- .../plugin_proceed_to_state_create_import.cpp | 51 +++++++++++++++---- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/ets2panda/public/es2panda_lib.cpp b/ets2panda/public/es2panda_lib.cpp index 3935c32f7d..575672669e 100644 --- a/ets2panda/public/es2panda_lib.cpp +++ b/ets2panda/public/es2panda_lib.cpp @@ -1279,7 +1279,15 @@ extern "C" void InsertETSImportDeclarationAndParse(es2panda_Context *context, es importDeclE2p->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); auto &stmt = parserProgram->Ast()->StatementsForUpdates(); - stmt.insert(stmt.begin(), importDeclE2p); + bool hasUseStatic = !stmt.empty() && stmt.front()->IsExpressionStatement(); + if (hasUseStatic) { + auto *expansion = stmt.front()->AsExpressionStatement()->GetExpression(); + hasUseStatic = hasUseStatic && expansion->IsStringLiteral() && + expansion->AsStringLiteral()->Str() == compiler::Signatures::STATIC_PROGRAM_FLAG; + } + size_t insertIndex = hasUseStatic ? 1 : 0; + + stmt.insert(stmt.begin() + insertIndex, importDeclE2p); importDeclE2p->SetParent(parserProgram->Ast()); ctx->parser->AsETSParser()->AddExternalSource(ctx->parser->AsETSParser()->ParseSources()); diff --git a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp index d795325136..968aecacd5 100644 --- a/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp +++ b/ets2panda/test/unit/plugin/plugin_proceed_to_state_create_import.cpp @@ -20,8 +20,11 @@ #include #include "macros.h" #include "util.h" +#include "generated/signatures.h" +#include "parser/program/program.h" #include "public/es2panda_lib.h" #include "ir/ets/etsImportDeclaration.h" +#include "ir/statements/expressionStatement.h" #include "utils/arena_containers.h" // NOLINTBEGIN @@ -97,6 +100,28 @@ bool TestInsertImportAfterParse(es2panda_Context *context, [[maybe_unused]] es2p return true; } +bool CheckFirstUseStatic(es2panda_Program *program) +{ + auto *parserProgram = reinterpret_cast(program); + auto &stmts = parserProgram->Ast()->StatementsForUpdates(); + if (stmts.empty()) { + return false; + } + auto *firstStmt = stmts.front(); + if (!firstStmt->IsExpressionStatement()) { + return false; + } + auto *expr = firstStmt->AsExpressionStatement()->GetExpression(); + if (!expr->IsStringLiteral()) { + return false; + } + auto *strLiteral = expr->AsStringLiteral(); + if (strLiteral->Str() != ark::es2panda::compiler::Signatures::STATIC_PROGRAM_FLAG) { + return false; + } + return true; +} + void InsertImportInHeaderAfterParse(es2panda_Context *context, [[maybe_unused]] es2panda_Config *config, es2panda_Program *program) { @@ -150,7 +175,7 @@ bool Find(es2panda_AstNode *ast) if (g_impl->AstNodeIsProgramConst(g_ctx, parent)) { size_t sizeOfStatements = 0; auto *statements = g_impl->BlockStatementStatements(g_ctx, parent, &sizeOfStatements); - statements[0] = importDeclaration; + statements[1] = importDeclaration; g_impl->BlockStatementSetStatements(g_ctx, parent, statements, sizeOfStatements); g_impl->AstNodeSetParent(g_ctx, importDeclaration, parent); std::string str(g_impl->AstNodeDumpEtsSrcConst(g_ctx, parent)); @@ -162,6 +187,12 @@ bool Find(es2panda_AstNode *ast) return false; } +void DestroyConfigAndContext(es2panda_Context *context, es2panda_Config *config) +{ + g_impl->DestroyContext(context); + g_impl->DestroyConfig(config); +} + int main(int argc, char **argv) { if (argc < MIN_ARGC) { @@ -176,7 +207,8 @@ int main(int argc, char **argv) std::cout << "LOAD SUCCESS" << std::endl; const char **args = const_cast(std::next(argv)); auto config = g_impl->CreateConfig(argc - 1, args); - auto source = std::string("import {A} from \"./export\" ;function foo() {let b:B = new B();let a:A = new A()}"); + auto source = std::string( + "\"use static\";import {A} from \"./export\" ;function foo() {let b:B = new B();let a:A = new A()}"); auto context = g_impl->CreateContextFromString(config, source.data(), *(std::next(argv, argc - 1))); if (context == nullptr) { @@ -193,36 +225,35 @@ int main(int argc, char **argv) return TEST_ERROR_CODE; } - if (!TestInsertImportAfterParse(context, config, program)) { + if (!TestInsertImportAfterParse(context, config, program) || !CheckFirstUseStatic(program)) { + DestroyConfigAndContext(context, config); return 1; } + InsertImportInHeaderAfterParse(context, config, program); g_impl->ProceedToState(context, ES2PANDA_STATE_BOUND); CheckForErrors("BOUND", context); g_impl->ProceedToState(context, ES2PANDA_STATE_CHECKED); - auto *rootAst = g_impl->ProgramAst(context, program); - std::cout << g_impl->AstNodeDumpEtsSrcConst(context, rootAst) << std::endl; CheckForErrors("CHECKED", context); auto *importDeclAfterCheck = CreateImportDecl(context, program, "A0", "A0", "./export2"); g_impl->InsertETSImportDeclarationAndParse(context, program, importDeclAfterCheck); - std::cout << g_impl->AstNodeDumpEtsSrcConst(context, rootAst) << std::endl; - auto *tagetFunc = GetTargetFunc(context, rootAst); + auto *tagetFunc = GetTargetFunc(context, ast); InsertStatementInFunctionBody(context, tagetFunc); - std::cout << g_impl->AstNodeDumpEtsSrcConst(context, rootAst) << std::endl; - g_impl->AstNodeRecheck(context, rootAst); + g_impl->AstNodeRecheck(context, ast); g_impl->ProceedToState(context, ES2PANDA_STATE_BIN_GENERATED); CheckForErrors("BIN", context); if (g_impl->ContextState(context) == ES2PANDA_STATE_ERROR) { + DestroyConfigAndContext(context, config); return PROCEED_ERROR_CODE; } - g_impl->DestroyConfig(config); + DestroyConfigAndContext(context, config); return 0; } -- Gitee From c24b316877a031e63a34436335536bdf6ed37fb4 Mon Sep 17 00:00:00 2001 From: zengyuan Date: Wed, 2 Jul 2025 20:20:11 +0800 Subject: [PATCH 018/107] Add scenarios for 'arkts-no-sparse-array' Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJJT9 Signed-off-by: zengyuan Change-Id: I5a1c5370a897a656883ee509c0014380a88706ea --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 32 +- .../src/lib/utils/consts/BuiltinWhiteList.ts | 7 + .../src/lib/utils/consts/TypedArrays.ts | 16 +- .../linter/test/main/no_sparse_array.ets | 67 +++- .../test/main/no_sparse_array.ets.arkts2.json | 192 ++-------- .../linter/test/main/no_sparse_array2.ets | 50 +++ .../test/main/no_sparse_array2.ets.args.json | 20 + .../main/no_sparse_array2.ets.arkts2.json | 348 ++++++++++++++++++ .../test/main/no_sparse_array2.ets.json | 17 + 9 files changed, 561 insertions(+), 188 deletions(-) create mode 100644 ets2panda/linter/test/main/no_sparse_array2.ets create mode 100644 ets2panda/linter/test/main/no_sparse_array2.ets.args.json create mode 100644 ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/no_sparse_array2.ets.json diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 1760649828..686c4cd278 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -54,6 +54,8 @@ import { TASKPOOL } from './utils/consts/SendableAPI'; import { DEFAULT_COMPATIBLE_SDK_VERSION, DEFAULT_COMPATIBLE_SDK_VERSION_STAGE } from './utils/consts/VersionInfo'; +import { TYPED_ARRAYS } from './utils/consts/TypedArrays'; +import { BUILTIN_CONSTRUCTORS } from './utils/consts/BuiltinWhiteList'; import { forEachNodeInSubtree } from './utils/functions/ForEachNodeInSubtree'; import { hasPredecessor } from './utils/functions/HasPredecessor'; import { isStdLibrarySymbol, isStdLibraryType } from './utils/functions/IsStdLibrary'; @@ -690,20 +692,22 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { const parent = arrayLitNode.parent; const arrayLitElements = arrayLitNode.elements; const arrayElementIsEmpty = arrayLitElements.length === 0; - let emptyContextTypeForArrayLiteral = false; /* * check that array literal consists of inferrable types * e.g. there is no element which is untyped object literals */ - const isPromiseEmptyArray = this.checkPromiseEmptyArray(parent, arrayElementIsEmpty); - const isEmptyArray = this.options.arkts2 && !arrayLitType && arrayElementIsEmpty; - if (isPromiseEmptyArray) { - this.incrementCounters(arrayLitNode, FaultID.NosparseArray); - } else if (isEmptyArray) { - this.incrementCounters(node, FaultID.NosparseArray); + const isPromiseCallExpression = TypeScriptLinter.checkPromiseCallExpression(parent); + const isTypedArrayOrBuiltInConstructor = TypeScriptLinter.checkTypedArrayOrBuiltInConstructor(parent); + if (this.options.arkts2 && arrayElementIsEmpty) { + if (!arrayLitType) { + this.incrementCounters(node, FaultID.NosparseArray); + } else if (isPromiseCallExpression || isTypedArrayOrBuiltInConstructor) { + this.incrementCounters(arrayLitNode, FaultID.NosparseArray); + } } + let emptyContextTypeForArrayLiteral = false; for (const element of arrayLitElements) { const elementContextType = this.tsTypeChecker.getContextualType(element); if (ts.isObjectLiteralExpression(element)) { @@ -727,8 +731,18 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } - private checkPromiseEmptyArray(parent: ts.Node, arrayElementIsEmpty: boolean): boolean { - if (this.options.arkts2 && ts.isCallExpression(parent) && arrayElementIsEmpty) { + private static checkTypedArrayOrBuiltInConstructor(parent: ts.Node): boolean { + if (ts.isNewExpression(parent)) { + const newExpr = parent as ts.NewExpression; + const typeName = newExpr.expression.getText(); + + return TYPED_ARRAYS.includes(typeName) || BUILTIN_CONSTRUCTORS.includes(typeName); + } + return false; + } + + private static checkPromiseCallExpression(parent: ts.Node): boolean { + if (ts.isCallExpression(parent)) { const callExpr = parent; const methodName = TypeScriptLinter.getPromiseMethodName(callExpr.expression); if (methodName && PROMISE_METHODS.has(methodName)) { diff --git a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts index d4e4898557..a491289280 100644 --- a/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts +++ b/ets2panda/linter/src/lib/utils/consts/BuiltinWhiteList.ts @@ -45,3 +45,10 @@ export const BUILTIN_DISABLE_CALLSIGNATURE = [ 'TypeError', 'URIError' ]; + +export const BUILTIN_CONSTRUCTORS = [ + 'Boolean', + 'Number', + 'Object', + 'String' +]; \ No newline at end of file diff --git a/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts b/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts index b2d07bfe39..5ae541d9ca 100644 --- a/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts +++ b/ets2panda/linter/src/lib/utils/consts/TypedArrays.ts @@ -14,15 +14,15 @@ */ export const TYPED_ARRAYS = [ + 'BigInt64Array', + 'BigUint64Array', + 'Float32Array', + 'Float64Array', 'Int8Array', - 'Uint8ClampedArray', - 'Uint8Array', - 'Uint16Array', 'Int16Array', - 'Uint32Array', 'Int32Array', - 'Float64Array', - 'Float32Array', - 'BigUint64Array', - 'BigInt64Array' + 'Uint8Array', + 'Uint8ClampedArray', + 'Uint16Array', + 'Uint32Array' ]; diff --git a/ets2panda/linter/test/main/no_sparse_array.ets b/ets2panda/linter/test/main/no_sparse_array.ets index eb1ba59ca1..e8e2ef3ba4 100644 --- a/ets2panda/linter/test/main/no_sparse_array.ets +++ b/ets2panda/linter/test/main/no_sparse_array.ets @@ -13,21 +13,11 @@ * limitations under the License. */ -let a = [1, , , 3]; -let b = []; -let c: number[] = []; - -let d = Promise.race([]); -let e = Promise.all([]); -let f = Promise.allSettled([]); -let g = Promise.any([]); -let h = Promise.resolve([]); +/* + * Shouldn't report (arkts-no-sparse-array) + */ -let d1 = Promise.race([]); -let e1 = Promise.all([]); -let f1 = Promise.allSettled([]); -let g1 = Promise.any([]); -let h1 = Promise.resolve([]); +let c: number[] = []; let i = Promise.race([1.0]); let j = Promise.all([2.0]); @@ -39,4 +29,51 @@ let i1 = Promise.race([1]); let j1 = Promise.all([2]); let k1 = Promise.allSettled([3]); let l1 = Promise.any([4]); -let m1 = Promise.resolve([5]); \ No newline at end of file +let m1 = Promise.resolve([5]); + +let bigInt64 = new BigInt64Array([1.0]); +let bigUint64 = new BigUint64Array([1.0]); +let floast64 = new Float64Array([1.0]); +let float32 = new Float32Array([1.0]); +let int32 = new Int32Array([1.0]); +let int64 = new Int16Array([1.0]); +let int8 = new Int8Array([1.0]); +let uint32 = new Uint32Array([1.0]); +let uint64 = new Uint16Array([1.0]); +let uint8 = new Uint8Array([1.0]); +let uint8Clamped = new Uint8ClampedArray([1.0]); + +let str1 = new String(['1']); +let bool1 = new Boolean(['1']); +let num1 = new Number(['1']); +let obj1 = new Object(['1']); + +function foo(arr: number[]) { + return; +} +foo([]); + +function foo1(arr: Array) { + return; +} +foo1([]); + +function foo2(a: T) { + return; +} +foo2([]); + +function foo3(a: T[]) { + return; +} +foo3([]); + +function foo4(a: T) { + return; +} +foo4([]); + +function foo5(a: T[]) { + return; +} +foo5([]); diff --git a/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json index 103a56a139..a56b997f6e 100644 --- a/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json +++ b/ets2panda/linter/test/main/no_sparse_array.ets.arkts2.json @@ -15,203 +15,83 @@ ], "result": [ { - "line": 16, - "column": 12, - "endLine": 16, - "endColumn": 12, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 14, - "endLine": 16, - "endColumn": 14, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 10, - "endLine": 16, - "endColumn": 11, + "line": 28, + "column": 24, + "endLine": 28, + "endColumn": 25, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 16, - "column": 17, - "endLine": 16, - "endColumn": 18, + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 24, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 17, - "column": 9, - "endLine": 17, - "endColumn": 11, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 20, + "line": 30, "column": 30, - "endLine": 20, - "endColumn": 32, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 29, - "endLine": 21, - "endColumn": 31, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 36, - "endLine": 22, - "endColumn": 38, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 23, - "column": 29, - "endLine": 23, + "endLine": 30, "endColumn": 31, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 24, - "column": 35, - "endLine": 24, - "endColumn": 37, - "problem": "NosparseArray", + "problem": "NumericSemantics", "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 26, + "line": 31, "column": 23, - "endLine": 26, - "endColumn": 25, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 22, - "endLine": 27, + "endLine": 31, "endColumn": 24, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 28, - "column": 29, - "endLine": 28, - "endColumn": 31, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 29, - "column": 22, - "endLine": 29, - "endColumn": 24, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 30, - "column": 26, - "endLine": 30, - "endColumn": 28, - "problem": "NosparseArray", - "suggest": "", - "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 24, - "endLine": 38, - "endColumn": 25, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 39, - "column": 23, - "endLine": 39, - "endColumn": 24, + "line": 32, + "column": 27, + "endLine": 32, + "endColumn": 28, "problem": "NumericSemantics", "suggest": "", "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, { - "line": 40, - "column": 30, - "endLine": 40, - "endColumn": 31, - "problem": "NumericSemantics", + "line": 46, + "column": 12, + "endLine": 46, + "endColumn": 29, + "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", "severity": "ERROR" }, { - "line": 41, - "column": 23, - "endLine": 41, - "endColumn": 24, - "problem": "NumericSemantics", + "line": 47, + "column": 13, + "endLine": 47, + "endColumn": 31, + "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", "severity": "ERROR" }, { - "line": 42, - "column": 27, - "endLine": 42, - "endColumn": 28, - "problem": "NumericSemantics", + "line": 48, + "column": 12, + "endLine": 48, + "endColumn": 29, + "problem": "CreatingPrimitiveTypes", "suggest": "", - "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", "severity": "ERROR" } ] diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets b/ets2panda/linter/test/main/no_sparse_array2.ets new file mode 100644 index 0000000000..5e923a25cb --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets @@ -0,0 +1,50 @@ +/* + * 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. + */ + +/* + * Should report (arkts-no-sparse-array) + */ + +let a = [1, , , 3]; +let b = []; + +let d = Promise.race([]); +let e = Promise.all([]); +let f = Promise.allSettled([]); +let g = Promise.any([]); +let h = Promise.resolve([]); + +let d1 = Promise.race([]); +let e1 = Promise.all([]); +let f1 = Promise.allSettled([]); +let g1 = Promise.any([]); +let h1 = Promise.resolve([]); + +let bigInt64 = new BigInt64Array([]); +let bigUint64 = new BigUint64Array([]); +let floast64 = new Float64Array([]); +let float32 = new Float32Array([]); +let int32 = new Int32Array([]); +let int64 = new Int16Array([]); +let int8 = new Int8Array([]); +let uint32 = new Uint32Array([]); +let uint64 = new Uint16Array([]); +let uint8 = new Uint8Array([]); +let uint8Clamped = new Uint8ClampedArray([]); + +let str1 = new String([]); +let bool1 = new Boolean([]); +let num1 = new Number([]); +let obj1 = new Object([]); diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.args.json b/ets2panda/linter/test/main/no_sparse_array2.ets.args.json new file mode 100644 index 0000000000..ddcd120faf --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets.args.json @@ -0,0 +1,20 @@ +{ + "copyright": [ + "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." + ], + "mode": { + "arkts2": "" + } + } + \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json b/ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json new file mode 100644 index 0000000000..c9499abe6c --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets.arkts2.json @@ -0,0 +1,348 @@ +{ + "copyright": [ + "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." + ], + "result": [ + { + "line": 20, + "column": 12, + "endLine": 20, + "endColumn": 12, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 14, + "endLine": 20, + "endColumn": 14, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 10, + "endLine": 20, + "endColumn": 11, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 20, + "column": 17, + "endLine": 20, + "endColumn": 18, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 9, + "endLine": 21, + "endColumn": 11, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 30, + "endLine": 23, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 24, + "column": 29, + "endLine": 24, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 25, + "column": 36, + "endLine": 25, + "endColumn": 38, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 26, + "column": 29, + "endLine": 26, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 35, + "endLine": 27, + "endColumn": 37, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 23, + "endLine": 29, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 22, + "endLine": 30, + "endColumn": 24, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 29, + "endLine": 31, + "endColumn": 31, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 22, + "endLine": 32, + "endColumn": 24, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 26, + "endLine": 33, + "endColumn": 28, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 35, + "column": 34, + "endLine": 35, + "endColumn": 36, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 36, + "endLine": 36, + "endColumn": 38, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 37, + "column": 33, + "endLine": 37, + "endColumn": 35, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 32, + "endLine": 38, + "endColumn": 34, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 28, + "endLine": 39, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 28, + "endLine": 40, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 26, + "endLine": 41, + "endColumn": 28, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 30, + "endLine": 42, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 30, + "endLine": 43, + "endColumn": 32, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 44, + "column": 28, + "endLine": 44, + "endColumn": 30, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 42, + "endLine": 45, + "endColumn": 44, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 12, + "endLine": 47, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 23, + "endLine": 47, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 13, + "endLine": 48, + "endColumn": 28, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 25, + "endLine": 48, + "endColumn": 27, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 12, + "endLine": 49, + "endColumn": 26, + "problem": "CreatingPrimitiveTypes", + "suggest": "", + "rule": "Primitive types are normalized with their boxed type (arkts-primitive-type-normalization)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 23, + "endLine": 49, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 23, + "endLine": 50, + "endColumn": 25, + "problem": "NosparseArray", + "suggest": "", + "rule": "Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/no_sparse_array2.ets.json b/ets2panda/linter/test/main/no_sparse_array2.ets.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/no_sparse_array2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file -- Gitee From 977f8f6613518b7450f0261511846873ed6bc276 Mon Sep 17 00:00:00 2001 From: ZhongNing Date: Wed, 2 Jul 2025 10:14:43 +0800 Subject: [PATCH 019/107] Fix for MethodInheritRule Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJ5FN Test scenarios: fix bug Signed-off-by: ZhongNing --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 55 +++++- .../linter/test/main/method_inheritance.ets | 80 ++++++++- .../main/method_inheritance.ets.arkts2.json | 156 +++++++++++++++++- .../test/main/method_inheritance.ets.json | 33 +++- .../linter/test/main/method_inheritance_ts.ts | 17 ++ .../test/main/method_inheritance_ts.ts.json | 28 ++++ 6 files changed, 355 insertions(+), 14 deletions(-) create mode 100644 ets2panda/linter/test/main/method_inheritance_ts.ts create mode 100644 ets2panda/linter/test/main/method_inheritance_ts.ts.json diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 70ab7059c2..9ed3054eca 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -3578,25 +3578,66 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { ): void { const baseMethodType = this.getActualReturnType(baseMethod); const derivedMethodType = this.getActualReturnType(derivedMethod); - const baseMethodTypeIsVoid = baseMethodType && TsUtils.isVoidType(baseMethodType) || !baseMethod.type; - const derivedMethodTypeIsVoid = derivedMethodType && TsUtils.isVoidType(derivedMethodType); - if (baseMethodTypeIsVoid && derivedMethod.type && !derivedMethodTypeIsVoid) { - this.incrementCounters(derivedMethod.type, FaultID.MethodInheritRule); + const baseMethodTypeIsVoid = TypeScriptLinter.checkMethodTypeIsVoidOrAny(baseMethodType, true); + const baseMethodTypeisAny = TypeScriptLinter.checkMethodTypeIsVoidOrAny(baseMethodType, false); + const derivedMethodTypeIsVoid = TypeScriptLinter.checkMethodTypeIsVoidOrAny(derivedMethodType, true, true); + const baseMethodTypeisAnyWithVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + derivedMethodTypeIsVoid + ); + const baseMethodTypeisAnyWithPromiseVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + this.hasPromiseVoidReturn(derivedMethod) + ); + const baseMethodTypeIsVoidWithoutVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoid, + !derivedMethodTypeIsVoid + ); + const baseMethodTypeisAnyWithoutVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeisAny, + !derivedMethodTypeIsVoid + ); + const baseMethodTypeIsVoidWithVoid = TypeScriptLinter.getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoid, + derivedMethodTypeIsVoid + ); + if (baseMethodTypeisAnyWithVoid || baseMethodTypeIsVoidWithoutVoid || baseMethodTypeisAnyWithPromiseVoid) { + this.incrementCounters(derivedMethod.type ? derivedMethod.type : derivedMethod.name, FaultID.MethodInheritRule); return; } - - if (!baseMethodType || !derivedMethodType || baseMethodTypeIsVoid && derivedMethodTypeIsVoid) { + const isNoNeedCheck = + !baseMethodType || !derivedMethodType || baseMethodTypeisAnyWithoutVoid || baseMethodTypeIsVoidWithVoid; + if (isNoNeedCheck) { return; } if (this.isDerivedTypeAssignable(derivedMethodType, baseMethodType)) { return; } - if (!this.isTypeAssignable(derivedMethodType, baseMethodType)) { this.incrementCounters(derivedMethod.type ? derivedMethod.type : derivedMethod.name, FaultID.MethodInheritRule); } } + private static checkMethodTypeIsVoidOrAny( + methodType: ts.Type | undefined, + isVoidOrAny: boolean, + isDerived?: boolean + ): boolean | ts.TypeNode | undefined { + if (isDerived && isVoidOrAny) { + return methodType && TsUtils.isVoidType(methodType); + } else if (isVoidOrAny) { + return methodType && TsUtils.isVoidType(methodType); + } + return methodType && TsUtils.isAnyType(methodType); + } + + private static getRelationBaseMethodAndDerivedMethod( + baseMethodTypeIsVoidOrAny: boolean | ts.TypeNode | undefined, + derivedMethodCheckFlag: boolean | ts.TypeNode | undefined + ): boolean | ts.TypeNode | undefined { + return baseMethodTypeIsVoidOrAny && derivedMethodCheckFlag; + } + private getActualReturnType(method: ts.MethodDeclaration | ts.MethodSignature): ts.Type | undefined { let type: ts.Type | undefined; if (method.type) { diff --git a/ets2panda/linter/test/main/method_inheritance.ets b/ets2panda/linter/test/main/method_inheritance.ets index b82dcc042b..12c5ac3f16 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets +++ b/ets2panda/linter/test/main/method_inheritance.ets @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import {AAA} from './method_inheritance_ts' abstract class Y { abstract getDataByName(name: string | number, albumUri: string): Promise; } @@ -272,18 +272,92 @@ class Child1 extends Parent{ } } + +class Child11 extends Parent{ + async foo():Promise{ //error + + } +} +class Child12 extends Parent{ + async foo():Promise{ //error + return ''; + } +} +abstract class Child13 extends Parent{ + async foo():Promise{ //error + return ''; + } +} +abstract class Child14 extends Parent{ + async foo():Promise{ //error + + } +} + abstract class Child2 extends Parent{ - foo(): void { + foo(): void { //error } } abstract class Child3 extends Parent{ - foo(): boolean { //error + foo(): boolean { return false; } } + +class Child17 extends Parent{ + foo(){ //error??? + } +} +abstract class Child18 extends Parent{ + foo(){ //error??? + } +} + +class Child19 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child20 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child21 extends Parent{ + foo(){ //error + let aa :Promise; + return aa; + } +} +abstract class Child5 extends Parent1{ + async foo(): Promise{ //error + return ''; + } +} + abstract class Child4 extends Parent1{ async foo() { + } +} + +class CCC {} +class BBB extends AAA { + test(): CCC { + return new CCC(); + } +} + +class BBB2 extends AAA { + test(): void { //error + return ; + } +} + +class BBB3 extends AAA { + test() { //error } } \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json index 68eaed003e..ff24918722 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json +++ b/ets2panda/linter/test/main/method_inheritance.ets.arkts2.json @@ -315,14 +315,164 @@ "severity": "ERROR" }, { - "line": 281, + "line": 277, + "column": 15, + "endLine": 277, + "endColumn": 28, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 282, + "column": 15, + "endLine": 282, + "endColumn": 30, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 287, + "column": 15, + "endLine": 287, + "endColumn": 30, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 292, + "column": 15, + "endLine": 292, + "endColumn": 28, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 298, "column": 10, - "endLine": 281, - "endColumn": 17, + "endLine": 298, + "endColumn": 14, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 309, + "column": 3, + "endLine": 309, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 313, + "column": 3, + "endLine": 313, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 318, + "column": 3, + "endLine": 318, + "endColumn": 6, "problem": "MethodInheritRule", "suggest": "", "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", "severity": "ERROR" + }, + { + "line": 324, + "column": 3, + "endLine": 324, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 330, + "column": 3, + "endLine": 330, + "endColumn": 6, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 336, + "column": 16, + "endLine": 336, + "endColumn": 31, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 355, + "column": 11, + "endLine": 355, + "endColumn": 15, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 361, + "column": 3, + "endLine": 361, + "endColumn": 7, + "problem": "MethodInheritRule", + "suggest": "", + "rule": "Overridden method parameters and return types must respect type inheritance principles (arkts-method-inherit-rule)", + "severity": "ERROR" + }, + { + "line": 320, + "column": 12, + "endLine": 320, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 326, + "column": 12, + "endLine": 326, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 332, + "column": 12, + "endLine": 332, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance.ets.json b/ets2panda/linter/test/main/method_inheritance.ets.json index ca88f857e9..144f84de60 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets.json +++ b/ets2panda/linter/test/main/method_inheritance.ets.json @@ -13,5 +13,36 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], - "result": [] + "result": [ + { + "line": 320, + "column": 12, + "endLine": 320, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 326, + "column": 12, + "endLine": 326, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + }, + { + "line": 332, + "column": 12, + "endLine": 332, + "endColumn": 14, + "problem": "StrictDiagnostic", + "suggest": "Variable 'aa' is used before being assigned.", + "rule": "Variable 'aa' is used before being assigned.", + "severity": "ERROR" + } + ] } \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance_ts.ts b/ets2panda/linter/test/main/method_inheritance_ts.ts new file mode 100644 index 0000000000..f11bbedb83 --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_ts.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ +export abstract class AAA { + abstract test():any; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/method_inheritance_ts.ts.json b/ets2panda/linter/test/main/method_inheritance_ts.ts.json new file mode 100644 index 0000000000..a28a98c2bd --- /dev/null +++ b/ets2panda/linter/test/main/method_inheritance_ts.ts.json @@ -0,0 +1,28 @@ +{ + "copyright": [ + "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." + ], + "result": [ + { + "line": 16, + "column": 19, + "endLine": 16, + "endColumn": 22, + "problem": "AnyType", + "suggest": "", + "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "severity": "ERROR" + } + ] +} \ No newline at end of file -- Gitee From 9bf9d7cb37944aff51e36deee1fd59413ab96fdd Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Wed, 25 Jun 2025 21:57:50 +0800 Subject: [PATCH 020/107] Fix class extends bug Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICI1ZU?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ets/helpers.cpp | 2 +- ets2panda/checker/ets/object.cpp | 11 +- ets2panda/checker/ets/typeCreation.cpp | 3 - ets2panda/checker/ets/typeRelationContext.cpp | 1 + ets2panda/checker/types/gradualType.cpp | 3 +- ets2panda/compiler/core/ETSemitter.cpp | 2 +- .../compiler/lowering/ets/dynamicImport.cpp | 10 +- .../lowering/ets/gradualTypeNarrowing.cpp | 8 +- .../ets/interfaceObjectLiteralLowering.cpp | 20 +- .../compiler/lowering/ets/lambdaLowering.cpp | 8 +- .../lowering/ets/objectLiteralLowering.cpp | 32 +- .../compiler/lowering/ets/unboxLowering.cpp | 3 + ets2panda/ir/expressions/memberExpression.cpp | 9 +- .../dynamic_class_ctor_decl_import_bad.ets | 8 +- .../dynamic_class_interface.ets | 62 + .../modules/module-expected.txt | 1159 +++++++++++++---- .../dynamic_import_tests/modules/module.ets | 6 + 17 files changed, 1064 insertions(+), 283 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 6292556bb7..ae4b18808c 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -3174,7 +3174,7 @@ void ETSChecker::CheckTypeParameterVariance(ir::ClassDefinition *classDef) return; } - Context().SetContainingClass(classDef->TsType()->AsETSObjectType()); + Context().SetContainingClass(classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()); auto checkVariance = [this](VarianceFlag varianceFlag, ir::Expression *expression, Type *type) { Relation()->Result(RelationResult::TRUE); Relation()->SetNode(expression); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 7cfe16d58e..ad7a332f38 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -183,7 +183,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) return false; } - auto *superType = classDef->Super()->AsTypeNode()->GetType(this); + auto *superType = classDef->Super()->AsTypeNode()->GetType(this)->MaybeBaseTypeOfGradualType(); if (superType == nullptr) { return true; } @@ -215,6 +215,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) void ETSChecker::ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos) { + interface = interface->MaybeBaseTypeOfGradualType(); if (interface->IsETSObjectType() && interface->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)) { LogError(diagnostic::INTERFACE_EXTENDS_CLASS, {}, pos); return; @@ -471,7 +472,7 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; var->SetTsType(type); } else { - interfaceType = var->TsType()->AsETSObjectType(); + interfaceType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; } @@ -525,7 +526,7 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } } else if (var->TsType()->IsETSObjectType()) { - classType = var->TsType()->AsETSObjectType(); + classType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(classType) : classType; } else { ES2PANDA_ASSERT(IsAnyError()); @@ -2568,6 +2569,10 @@ Type *ETSChecker::GetApparentType(Type *type) return res; }; + if (type->IsGradualType()) { + return cached(type->AsGradualType()->GetBaseType()); + } + if (type->IsETSTypeParameter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return cached(GetApparentType(type->AsETSTypeParameter()->GetConstraintType())); diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 725024a0bb..85727571f9 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -133,9 +133,6 @@ Type *ETSChecker::CreateGradualType(Type *type, Language const lang) if (type->IsGradualType()) { return type; } - if (!type->PossiblyInForeignDomain()) { - return type; - } if (type->IsETSAnyType()) { return type; } diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index 80bfff4d4e..eb79912ef8 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -110,6 +110,7 @@ static void CheckInstantiationConstraints(ETSChecker *checker, ArenaVectorRelation(); for (auto type : typeParams) { + type = type->MaybeBaseTypeOfGradualType(); if (!type->IsETSTypeParameter()) { continue; } diff --git a/ets2panda/checker/types/gradualType.cpp b/ets2panda/checker/types/gradualType.cpp index cdb568ab47..8a80baa2a9 100644 --- a/ets2panda/checker/types/gradualType.cpp +++ b/ets2panda/checker/types/gradualType.cpp @@ -70,7 +70,8 @@ void GradualType::ToString(std::stringstream &ss, [[maybe_unused]] bool precise) Type *GradualType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) { - return baseType_->Instantiate(allocator, relation, globalTypes); + auto baseType = baseType_->Instantiate(allocator, relation, globalTypes); + return relation->GetChecker()->AsETSChecker()->CreateGradualType(baseType); } Type *GradualType::Substitute(TypeRelation *relation, const Substitution *substitution) diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index baf96ce455..287e4d50d9 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -656,7 +656,7 @@ void ETSEmitter::GenClassRecord(const ir::ClassDefinition *classDef, bool extern annotations.push_back(GenAnnotationModule(classDef)); } - if (!annotations.empty()) { + if (!annotations.empty() && !classDef->IsLazyImportObjectClass()) { classRecord.metadata->AddAnnotations(annotations); } diff --git a/ets2panda/compiler/lowering/ets/dynamicImport.cpp b/ets2panda/compiler/lowering/ets/dynamicImport.cpp index 08228d3af8..2801433e22 100644 --- a/ets2panda/compiler/lowering/ets/dynamicImport.cpp +++ b/ets2panda/compiler/lowering/ets/dynamicImport.cpp @@ -151,8 +151,9 @@ static void BuildLazyImportObject(public_lib::Context *ctx, ir::ETSImportDeclara } const auto className = classDecl->Definition()->Ident()->Name(); - if (declProgram->IsASTChecked()) { - checker->SetPropertiesForModuleObject(moduleMap.find(className)->second, importDecl->DeclPath(), nullptr); + auto found = moduleMap.find(className); + if (declProgram->IsASTChecked() && found != moduleMap.end()) { + checker->SetPropertiesForModuleObject(found->second, importDecl->DeclPath(), nullptr); return; } @@ -211,6 +212,7 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context return ident; } + auto newIdent = allocator->New(ident->Variable()->Name(), allocator); auto *leftId = allocator->New(varIt->second->Ident()->Name(), allocator); auto *rightId = allocator->New(FIELD_NAME, allocator); @@ -218,7 +220,7 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context allocator, leftId, rightId, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); auto *memberExpr = util::NodeAllocator::ForceSetParent( - allocator, expr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + allocator, expr, newIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); memberExpr->SetParent(parent); CheckLoweredNode(varBinder, checker, memberExpr); @@ -228,7 +230,7 @@ static AstNodePtr TransformIdentifier(ir::Identifier *ident, public_lib::Context bool DynamicImport::PerformForModule(public_lib::Context *ctx, parser::Program *program) { - auto allocator = ctx->Allocator(); + auto allocator = ctx->GetChecker()->ProgramAllocator(); ArenaUnorderedMap varMap {allocator->Adapter()}; ArenaUnorderedMap moduleMap {allocator->Adapter()}; diff --git a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp index 778b1a5949..ce9840672b 100644 --- a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp +++ b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp @@ -78,10 +78,10 @@ void GradualTypeNarrowing::NarrowGradualType(ir::AstNode *node) { auto typedNode = node->AsTyped(); auto typeTransformFunc = [this](checker::Type *type) -> checker::TypePtr { - if (type->IsGradualType()) { - return type->AsGradualType()->GetBaseType()->IsETSTypeParameter() - ? type->AsGradualType()->GetBaseType()->AsETSTypeParameter()->GetConstraintType() - : this->checker_->GlobalETSRelaxedAnyType(); + if (type->IsGradualType() || (type->IsETSObjectType() && type->AsETSObjectType()->GetDeclNode() != nullptr && + type->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType() != nullptr && + type->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType())) { + return this->checker_->GlobalETSRelaxedAnyType(); } return type; }; diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 753e708f12..21e3981ab2 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -289,7 +289,10 @@ static void GenerateAnonClassTypeFromAbstractClass(public_lib::Context *ctx, ir: auto *classDecl = checker->BuildClass(anonClassName.View(), classBodyBuilder); RefineSourceRanges(classDecl); auto *classDef = classDecl->Definition(); - auto *classType = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); + if (classDef->TsType()->IsGradualType()) { + return; + } + auto *classType = classDef->TsType()->AsETSObjectType(); classDecl->SetRange(abstractClassNode->Range()); classDef->SetAnonymousModifier(); @@ -378,6 +381,9 @@ static void HandleInterfaceLowering(public_lib::Context *ctx, ir::ObjectExpressi static bool CheckInterfaceShouldGenerateAnonClass(ir::TSInterfaceDeclaration *interfaceDecl) { + if (interfaceDecl->TsType() != nullptr && interfaceDecl->TsType()->IsGradualType()) { + return false; + } for (auto it : interfaceDecl->Body()->Body()) { if (it->IsOverloadDeclaration()) { continue; @@ -394,7 +400,7 @@ static bool CheckInterfaceShouldGenerateAnonClass(ir::TSInterfaceDeclaration *in static bool CheckAbstractClassShouldGenerateAnonClass(ir::ClassDefinition *classDef) { - auto constructorSigs = classDef->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType()->ConstructSignatures(); + auto constructorSigs = classDef->TsType()->AsETSObjectType()->ConstructSignatures(); if (auto res = std::find_if(constructorSigs.cbegin(), constructorSigs.cend(), [](checker::Signature *sig) -> bool { return sig->MinArgCount() == 0; }); res == constructorSigs.cend()) { @@ -415,7 +421,7 @@ static void TransfromInterfaceDecl(public_lib::Context *ctx, parser::Program *pr if (ast->IsTSInterfaceDeclaration() && CheckInterfaceShouldGenerateAnonClass(ast->AsTSInterfaceDeclaration())) { GenerateAnonClassTypeFromInterface(ctx, ast->AsTSInterfaceDeclaration()); } else if (ast->IsClassDefinition() && ast != program->GlobalClass() && - ast->AsClassDefinition()->IsAbstract() && + ast->AsClassDefinition()->IsAbstract() && !ast->AsClassDefinition()->TsType()->IsGradualType() && CheckAbstractClassShouldGenerateAnonClass(ast->AsClassDefinition())) { GenerateAnonClassTypeFromAbstractClass(ctx, ast->AsClassDefinition()); } @@ -425,8 +431,12 @@ static void TransfromInterfaceDecl(public_lib::Context *ctx, parser::Program *pr static void TransfromInterfaceLiteral(public_lib::Context *ctx, parser::Program *program) { program->Ast()->IterateRecursivelyPostorder([ctx](ir::AstNode *ast) -> void { - if (ast->IsObjectExpression() && (IsInterfaceType(ast->AsObjectExpression()->TsType()) || - IsAbstractClassType(ast->AsObjectExpression()->TsType()))) { + if (!ast->IsObjectExpression()) { + return; + } + auto objExpr = ast->AsObjectExpression(); + if ((IsInterfaceType(objExpr->TsType()) || IsAbstractClassType(objExpr->TsType())) && + !objExpr->TsType()->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType()) { HandleInterfaceLowering(ctx, ast->AsObjectExpression()); } }); diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 17cfcc6a9a..679d5cbfb5 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -340,10 +340,10 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar auto [params, vMap] = CreateLambdaCalleeParameters(ctx, lambda, *info->capturedVars, paramScope, &substitution); auto varMap = std::move(vMap); - auto *returnType = - cmInfo->forcedReturnType != nullptr - ? cmInfo->forcedReturnType - : lambda->Function()->Signature()->ReturnType()->Substitute(checker->Relation(), &substitution); + auto arrowReturnType = lambda->TsType()->AsETSFunctionType()->ArrowSignature()->ReturnType(); + auto *returnType = cmInfo->forcedReturnType != nullptr + ? cmInfo->forcedReturnType + : arrowReturnType->Substitute(checker->Relation(), &substitution); auto returnTypeAnnotation = allocator->New(returnType, allocator); auto funcFlags = ir::ScriptFunctionFlags::METHOD | cmInfo->auxFunctionFlags; diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index 8e0fbcfb05..7eacbf1793 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -293,6 +293,30 @@ static ir::AstNode *HandleObjectLiteralLowering(public_lib::Context *ctx, ir::Ob return loweringResult; } +static ir::AstNode *HandleDynamicObjectLiteralLowering(public_lib::Context *ctx, ir::ObjectExpression *objExpr) +{ + auto parser = ctx->parser->AsETSParser(); + auto checker = ctx->GetChecker()->AsETSChecker(); + auto varBinder = checker->VarBinder()->AsETSBinder(); + auto allocator = checker->ProgramAllocator(); + + std::stringstream ss; + ArenaVector blockStatements(allocator->Adapter()); + auto gensym = GenName(allocator); + blockStatements.push_back( + parser->CreateFormattedStatement("let @@I1:ESValue = ESValue.instantiateEmptyObject()", gensym)); + for (auto property : objExpr->Properties()) { + ss << "@@I1.setProperty('" + property->AsProperty()->Key()->DumpEtsSrc() + "', ESValue.wrap(" + + property->AsProperty()->Value()->DumpEtsSrc() + "))"; + } + blockStatements.push_back(parser->CreateFormattedStatement(ss.str(), gensym)); + blockStatements.push_back(parser->CreateFormattedStatement("@@I1", gensym)); + auto *blockExpr = util::NodeAllocator::ForceSetParent(allocator, std::move(blockStatements)); + blockExpr->SetParent(objExpr->Parent()); + CheckLoweredNode(varBinder, checker, blockExpr); + return blockExpr; +} + bool ObjectLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::Program *program) { program->Ast()->TransformChildrenRecursively( @@ -301,9 +325,15 @@ bool ObjectLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::P // Skip processing invalid and dynamic objects if (ast->IsObjectExpression()) { auto *exprType = ast->AsObjectExpression()->TsType(); - if (exprType != nullptr && exprType->IsETSObjectType()) { + if (exprType == nullptr) { + return ast; + } + if (exprType->IsETSObjectType()) { return HandleObjectLiteralLowering(ctx, ast->AsObjectExpression()); } + if (exprType->IsETSAnyType()) { + return HandleDynamicObjectLiteralLowering(ctx, ast->AsObjectExpression()); + } } return ast; }, diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 0e0ed70c0d..0e5299b822 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -724,6 +724,9 @@ static void HandleForOfStatement(UnboxContext *uctx, ir::ForOfStatement *forOf) // NOTE(gogabr): we need to recompute the right side type instead of just unboxing; // this may be, for example, a generic call that returns a boxed array. auto *tp = MaybeRecursivelyUnboxType(uctx, forOf->Right()->TsType()); + if (tp->IsETSAnyType()) { + return; + } checker::Type *elemTp = nullptr; if (tp->IsETSArrayType()) { diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index ae65ae697c..92ab181271 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -482,10 +482,11 @@ checker::Type *MemberExpression::HandleComputedInGradualType(checker::ETSChecker checker::Type *MemberExpression::CheckComputed(checker::ETSChecker *checker, checker::Type *baseType) { - if (baseType->IsGradualType()) { - auto objType = baseType->MaybeBaseTypeOfGradualType()->AsETSObjectType(); - SetObjectType(objType); - return HandleComputedInGradualType(checker, objType); + if (baseType->IsETSObjectType() && baseType->AsETSObjectType()->GetDeclNode() != nullptr && + baseType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType() != nullptr && + baseType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType()) { + SetObjectType(baseType->AsETSObjectType()); + return HandleComputedInGradualType(checker, baseType); } if (baseType->IsETSArrayType()) { auto *dflt = baseType->AsETSArrayType()->ElementType(); diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets index 349d936094..15a984dc8f 100644 --- a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_ctor_decl_import_bad.ets @@ -20,7 +20,9 @@ flags: [dynamic-ast] import { A } from "dynamic_import_tests/modules/module" function main(): void { - let x = /* @@ label */new A(/* @@ label1 */"abc", 10) + let x = new A("abc", 10) } -/* @@@ label1 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ -/* @@@ label Error TypeError: No matching construct signature for module.A("abc", Int) */ + +/* @@? 23:13 Error TypeError: Expected 0 arguments, got 2. */ +/* @@? 23:13 Error TypeError: No matching construct signature for module.A("abc", Int) */ +/* @@? 23:19 Error TypeError: Type '"abc"' is not compatible with type 'Double' at index 1 */ diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets new file mode 100644 index 0000000000..8d58a153b9 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_class_interface.ets @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { A, I, Animal } from "dynamic_import_tests/modules/module" + +let a = /* @@ label */new Animal() // CTE + +class Bird extends Animal { // OK + move(): void { } +} + +class C extends A { + override foo(p: double): string { + } //ok +} // ok + +let c = new C() +c.f1 // ok +C.f2 // ok +c./* @@ label1 */f3 // cte +c.foo(123) // ok +C.bar() // ok +c./* @@ label2 */foa() //cte + +class C1 implements I { // ok + s: string + f1(p: string): double { + return 12 + } + f2(p: double): string { + return "" + } +} + +function foo(i: I) { + i.s // ok + i./* @@ label3 */n // cte + i.f1("") // ok + i./* @@ label4 */f3() // cte +} + +/* @@@ label Error TypeError: Animal is abstract therefore cannot be instantiated. */ +/* @@@ label1 Error TypeError: Property 'f3' does not exist on type 'C' */ +/* @@@ label2 Error TypeError: Property 'foa' does not exist on type 'C' */ +/* @@@ label3 Error TypeError: Property 'n' does not exist on type 'I' */ +/* @@@ label4 Error TypeError: Property 'f3' does not exist on type 'I' */ \ No newline at end of file diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt index e4848fa057..409dcee411 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt @@ -214,88 +214,192 @@ "generator": false, "async": false, "expression": false, - "params": [ - { - "type": "ETSParameterExpression", - "name": { + "params": [], + "declare": true, + "loc": { + "start": { + "line": 22, + "column": 16, + "program": "module.ets" + }, + "end": { + "line": 22, + "column": 16, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 16, + "program": "module.ets" + }, + "end": { + "line": 22, + "column": 16, + "program": "module.ets" + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "kind": "constructor", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { "type": "Identifier", - "name": "p1", - "typeAnnotation": { - "type": "ETSPrimitiveType", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p1", + "typeAnnotation": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 23, + "column": 21, + "program": "module.ets" + }, + "end": { + "line": 23, + "column": 27, + "program": "module.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 17, + "program": "module.ets" + }, + "end": { + "line": 23, + "column": 27, + "program": "module.ets" + } + } + }, "loc": { "start": { - "line": 22, - "column": 21, + "line": 23, + "column": 17, "program": "module.ets" }, "end": { - "line": 22, + "line": 23, "column": 27, "program": "module.ets" } } }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 17, - "program": "module.ets" - }, - "end": { - "line": 22, - "column": 27, - "program": "module.ets" - } - } - }, - "loc": { - "start": { - "line": 22, - "column": 17, - "program": "module.ets" - }, - "end": { - "line": 22, - "column": 27, - "program": "module.ets" - } - } - }, - { - "type": "ETSParameterExpression", - "name": { - "type": "Identifier", - "name": "p2", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p2", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 33, + "program": "module.ets" + }, + "end": { + "line": 23, + "column": 39, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 33, + "program": "module.ets" + }, + "end": { + "line": 23, + "column": 40, + "program": "module.ets" + } + } + }, "loc": { "start": { - "line": 22, + "line": 23, "column": 33, "program": "module.ets" }, "end": { - "line": 22, - "column": 39, + "line": 23, + "column": 40, "program": "module.ets" } } }, + "decorators": [], "loc": { "start": { - "line": 22, - "column": 33, + "line": 23, + "column": 29, "program": "module.ets" }, "end": { - "line": 22, + "line": 23, "column": 40, "program": "module.ets" } @@ -303,73 +407,61 @@ }, "loc": { "start": { - "line": 22, - "column": 33, + "line": 23, + "column": 29, "program": "module.ets" }, "end": { - "line": 22, + "line": 23, "column": 40, "program": "module.ets" } } - }, - "decorators": [], - "loc": { - "start": { - "line": 22, - "column": 29, - "program": "module.ets" - }, - "end": { - "line": 22, - "column": 40, - "program": "module.ets" - } } - }, + ], + "declare": true, "loc": { "start": { - "line": 22, - "column": 29, + "line": 23, + "column": 16, "program": "module.ets" }, "end": { - "line": 22, - "column": 40, + "line": 23, + "column": 16, "program": "module.ets" } } + }, + "loc": { + "start": { + "line": 23, + "column": 16, + "program": "module.ets" + }, + "end": { + "line": 23, + "column": 16, + "program": "module.ets" + } } - ], - "declare": true, + }, + "overloads": [], + "decorators": [], "loc": { "start": { - "line": 22, - "column": 16, + "line": 23, + "column": 5, "program": "module.ets" }, "end": { - "line": 22, + "line": 23, "column": 16, "program": "module.ets" } } - }, - "loc": { - "start": { - "line": 22, - "column": 16, - "program": "module.ets" - }, - "end": { - "line": 22, - "column": 16, - "program": "module.ets" - } } - }, - "overloads": [], + ], "decorators": [], "loc": { "start": { @@ -392,12 +484,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 5, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" } @@ -418,12 +510,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 5, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" } @@ -442,12 +534,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 24, + "line": 25, "column": 12, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 18, "program": "module.ets" } @@ -456,12 +548,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 9, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 18, "program": "module.ets" } @@ -469,12 +561,12 @@ }, "loc": { "start": { - "line": 24, + "line": 25, "column": 9, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 18, "program": "module.ets" } @@ -491,12 +583,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 21, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 27, "program": "module.ets" } @@ -504,12 +596,12 @@ }, "loc": { "start": { - "line": 24, + "line": 25, "column": 21, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 28, "program": "module.ets" } @@ -517,12 +609,12 @@ }, "loc": { "start": { - "line": 24, + "line": 25, "column": 21, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 28, "program": "module.ets" } @@ -531,12 +623,12 @@ "declare": true, "loc": { "start": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" } @@ -544,12 +636,12 @@ }, "loc": { "start": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" } @@ -559,12 +651,12 @@ "decorators": [], "loc": { "start": { - "line": 24, + "line": 25, "column": 5, "program": "module.ets" }, "end": { - "line": 24, + "line": 25, "column": 8, "program": "module.ets" } @@ -578,12 +670,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 26, "column": 12, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" } @@ -604,12 +696,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 26, "column": 12, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" } @@ -623,12 +715,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 25, + "line": 26, "column": 19, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 25, "program": "module.ets" } @@ -637,12 +729,12 @@ "declare": true, "loc": { "start": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" } @@ -650,12 +742,12 @@ }, "loc": { "start": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" } @@ -665,12 +757,12 @@ "decorators": [], "loc": { "start": { - "line": 25, + "line": 26, "column": 5, "program": "module.ets" }, "end": { - "line": 25, + "line": 26, "column": 15, "program": "module.ets" } @@ -684,12 +776,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 5, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -710,12 +802,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 5, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -734,12 +826,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 26, + "line": 27, "column": 22, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 28, "program": "module.ets" } @@ -748,12 +840,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 18, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 28, "program": "module.ets" } @@ -761,12 +853,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 18, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 28, "program": "module.ets" } @@ -783,12 +875,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 31, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 37, "program": "module.ets" } @@ -796,12 +888,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 31, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 38, "program": "module.ets" } @@ -809,12 +901,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 31, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 38, "program": "module.ets" } @@ -835,12 +927,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -852,12 +944,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -865,12 +957,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -878,12 +970,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -891,12 +983,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -911,12 +1003,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -927,12 +1019,12 @@ "value": 0, "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -947,12 +1039,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -961,12 +1053,12 @@ ], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -975,12 +1067,12 @@ ], "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -988,12 +1080,12 @@ }, "loc": { "start": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -1003,12 +1095,12 @@ "decorators": [], "loc": { "start": { - "line": 26, + "line": 27, "column": 5, "program": "module.ets" }, "end": { - "line": 26, + "line": 27, "column": 17, "program": "module.ets" } @@ -1022,7 +1114,7 @@ "program": "module.ets" }, "end": { - "line": 28, + "line": 29, "column": 7, "program": "module.ets" } @@ -1035,7 +1127,7 @@ "program": "module.ets" }, "end": { - "line": 28, + "line": 29, "column": 7, "program": "module.ets" } @@ -1050,22 +1142,22 @@ "type": "MethodDefinition", "key": { "type": "Identifier", - "name": "f1", + "name": "s", "decorators": [], "loc": { "start": { - "line": 29, - "column": 5, - "program": "module.ets" + "line": 1, + "column": 1, + "program": null }, "end": { - "line": 29, - "column": 7, - "program": "module.ets" + "line": 1, + "column": 1, + "program": null } } }, - "kind": "method", + "kind": "get", "accessibility": "public", "static": false, "optional": false, @@ -1076,46 +1168,354 @@ "type": "ScriptFunction", "id": { "type": "Identifier", - "name": "f1", + "name": "s", "decorators": [], "loc": { "start": { - "line": 29, - "column": 5, - "program": "module.ets" + "line": 1, + "column": 1, + "program": null }, "end": { - "line": 29, - "column": 7, - "program": "module.ets" + "line": 1, + "column": 1, + "program": null } } }, "generator": false, "async": false, "expression": false, - "params": [ - { - "type": "ETSParameterExpression", + "params": [], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", "name": { "type": "Identifier", - "name": "p", - "typeAnnotation": { - "type": "ETSTypeReference", - "part": { - "type": "ETSTypeReferencePart", - "name": { - "type": "Identifier", - "name": "string", - "decorators": [], - "loc": { - "start": { - "line": 29, - "column": 11, + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 30, + "column": 13, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "overloads": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "kind": "set", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "s", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 30, + "column": 13, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 7, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 30, + "column": 6, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 30, + "column": 6, + "program": "module.ets" + } + } + } + ], + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + } + ], + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "f1", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "f1", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 31, + "column": 7, + "program": "module.ets" + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "p", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 31, + "column": 11, + "program": "module.ets" + }, + "end": { + "line": 31, "column": 17, "program": "module.ets" } @@ -1123,12 +1523,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 11, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 18, "program": "module.ets" } @@ -1136,12 +1536,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 11, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 18, "program": "module.ets" } @@ -1150,12 +1550,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 31, "column": 8, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 18, "program": "module.ets" } @@ -1163,12 +1563,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 8, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 18, "program": "module.ets" } @@ -1179,12 +1579,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 29, + "line": 31, "column": 20, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 26, "program": "module.ets" } @@ -1193,12 +1593,12 @@ "declare": true, "loc": { "start": { - "line": 29, + "line": 31, "column": 7, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 26, "program": "module.ets" } @@ -1206,12 +1606,12 @@ }, "loc": { "start": { - "line": 29, + "line": 31, "column": 7, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 26, "program": "module.ets" } @@ -1221,12 +1621,12 @@ "decorators": [], "loc": { "start": { - "line": 29, + "line": 31, "column": 5, "program": "module.ets" }, "end": { - "line": 29, + "line": 31, "column": 27, "program": "module.ets" } @@ -1240,12 +1640,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 5, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 7, "program": "module.ets" } @@ -1266,12 +1666,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 5, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 7, "program": "module.ets" } @@ -1290,12 +1690,12 @@ "type": "ETSPrimitiveType", "loc": { "start": { - "line": 30, + "line": 32, "column": 11, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 17, "program": "module.ets" } @@ -1304,12 +1704,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 8, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 17, "program": "module.ets" } @@ -1317,12 +1717,12 @@ }, "loc": { "start": { - "line": 30, + "line": 32, "column": 8, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 17, "program": "module.ets" } @@ -1339,12 +1739,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 20, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 26, "program": "module.ets" } @@ -1352,12 +1752,12 @@ }, "loc": { "start": { - "line": 30, + "line": 32, "column": 20, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 27, "program": "module.ets" } @@ -1365,12 +1765,12 @@ }, "loc": { "start": { - "line": 30, + "line": 32, "column": 20, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 27, "program": "module.ets" } @@ -1379,12 +1779,12 @@ "declare": true, "loc": { "start": { - "line": 30, + "line": 32, "column": 7, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 27, "program": "module.ets" } @@ -1392,12 +1792,12 @@ }, "loc": { "start": { - "line": 30, + "line": 32, "column": 7, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 27, "program": "module.ets" } @@ -1407,12 +1807,12 @@ "decorators": [], "loc": { "start": { - "line": 30, + "line": 32, "column": 5, "program": "module.ets" }, "end": { - "line": 30, + "line": 32, "column": 27, "program": "module.ets" } @@ -1421,12 +1821,12 @@ ], "loc": { "start": { - "line": 28, + "line": 29, "column": 28, "program": "module.ets" }, "end": { - "line": 31, + "line": 33, "column": 2, "program": "module.ets" } @@ -1438,12 +1838,12 @@ "decorators": [], "loc": { "start": { - "line": 28, + "line": 29, "column": 26, "program": "module.ets" }, "end": { - "line": 28, + "line": 29, "column": 27, "program": "module.ets" } @@ -1452,12 +1852,273 @@ "extends": [], "loc": { "start": { - "line": 28, + "line": 29, "column": 16, "program": "module.ets" }, "end": { - "line": 31, + "line": 35, + "column": 7, + "program": "module.ets" + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "Animal", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 31, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 37, + "program": "module.ets" + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "move", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 14, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 18, + "program": "module.ets" + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "move", + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 14, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 18, + "program": "module.ets" + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 36, + "column": 22, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 26, + "program": "module.ets" + } + } + }, + "declare": true, + "loc": { + "start": { + "line": 36, + "column": 18, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 18, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 36, + "column": 18, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 18, + "program": "module.ets" + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 36, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 36, + "column": 18, + "program": "module.ets" + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 39, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 39, + "program": "module.ets" + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 35, + "column": 39, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 39, + "program": "module.ets" + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 35, + "column": 39, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 39, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 39, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 39, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 39, + "program": "module.ets" + }, + "end": { + "line": 35, + "column": 39, + "program": "module.ets" + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "loc": { + "start": { + "line": 35, + "column": 38, + "program": "module.ets" + }, + "end": { + "line": 37, + "column": 2, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 35, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 37, "column": 2, "program": "module.ets" } @@ -2045,7 +2706,7 @@ "program": "module.ets" }, "end": { - "line": 31, + "line": 37, "column": 2, "program": "module.ets" } diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets index 055de415ec..500594f817 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets @@ -19,6 +19,7 @@ export declare class A { f1: string; static f2: double; + constructor() constructor(p1: double, p2: string); foo(p: double): string; @@ -26,6 +27,11 @@ export declare class A { optional_foo(p?: double): string; } export declare interface I { + s:string f1(p: string): double; f2(p: double): string; +} + +export declare abstract class Animal { + abstract move(): void } \ No newline at end of file -- Gitee From ab91542da16785ddc45acf236470f684397a23bb Mon Sep 17 00:00:00 2001 From: HuSenlin Date: Mon, 30 Jun 2025 23:27:38 +0800 Subject: [PATCH 021/107] Add commandLine progress bar Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIYO8 Signed-off-by: HuSenlin --- ets2panda/linter/package.json | 1 + ets2panda/linter/src/lib/CookBookMsg.ts | 10 + ets2panda/linter/src/lib/LinterRunner.ts | 55 +++-- .../src/lib/progress/CmdProgressInfo.ts | 26 +++ .../src/lib/progress/FixedLineProgressBar.ts | 200 ++++++++++++++++++ .../src/lib/{ => progress}/MigrationInfo.ts | 0 .../src/lib/{ => progress}/ProgressBarInfo.ts | 2 +- .../src/lib/statistics/scan/CountNapiFile.ts | 11 +- .../scan/ProblemStatisticsCommonFunction.ts | 5 +- 9 files changed, 286 insertions(+), 24 deletions(-) create mode 100644 ets2panda/linter/src/lib/progress/CmdProgressInfo.ts create mode 100644 ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts rename ets2panda/linter/src/lib/{ => progress}/MigrationInfo.ts (100%) rename ets2panda/linter/src/lib/{ => progress}/ProgressBarInfo.ts (93%) diff --git a/ets2panda/linter/package.json b/ets2panda/linter/package.json index c22b0da143..79b9616cac 100644 --- a/ets2panda/linter/package.json +++ b/ets2panda/linter/package.json @@ -49,6 +49,7 @@ "coverage-report": "node scripts/testRunner/coverage_report.js" }, "dependencies": { + "cli-progress": "^3.12.0", "commander": "^9.4.0", "fs-extra": "11.2.0", "homecheck": "file:./homecheck", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 31ef5659cb..764925ae68 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -16,6 +16,16 @@ export const cookBookMsg: string[] = []; export const cookBookTag: string[] = []; +/** + * @note If the value contains multiple parentheses groups, + * the rule name must be placed in the last group. + * + * @example + * // Correct (rule name in last parentheses): + * 'cookBookTag[352] = "1.2 Void conflict...(sdk-ability-asynchronous-lifecycle)"' + * +*/ + cookBookTag[1] = 'Objects with property names that are not identifiers are not supported (arkts-identifiers-as-prop-names)'; cookBookTag[2] = '"Symbol()" API is not supported (arkts-no-symbol)'; diff --git a/ets2panda/linter/src/lib/LinterRunner.ts b/ets2panda/linter/src/lib/LinterRunner.ts index d14aac0f8d..113f67fd1b 100644 --- a/ets2panda/linter/src/lib/LinterRunner.ts +++ b/ets2panda/linter/src/lib/LinterRunner.ts @@ -16,7 +16,6 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import * as ts from 'typescript'; -import { processSyncErr } from '../lib/utils/functions/ProcessWrite'; import * as qEd from './autofixes/QuasiEditor'; import type { BaseTypeScriptLinter } from './BaseTypeScriptLinter'; import type { CommandLineOptions } from './CommandLineOptions'; @@ -25,9 +24,16 @@ import type { LinterConfig } from './LinterConfig'; import type { LinterOptions } from './LinterOptions'; import type { LintRunResult } from './LintRunResult'; import { Logger } from './Logger'; -import type { MigrationInfo } from './MigrationInfo'; import type { ProblemInfo } from './ProblemInfo'; -import type { ProgressBarInfo } from './ProgressBarInfo'; +import type { CmdProgressInfo } from './progress/CmdProgressInfo'; +import { + FixedLineProgressBar, + postProcessCmdProgressBar, + preProcessCmdProgressBar, + processCmdProgressBar +} from './progress/FixedLineProgressBar'; +import type { MigrationInfo } from './progress/MigrationInfo'; +import type { ProgressBarInfo } from './progress/ProgressBarInfo'; import { ProjectStatistics } from './statistics/ProjectStatistics'; import { generateMigrationStatisicsReport } from './statistics/scan/ProblemStatisticsCommonFunction'; import type { TimeRecorder } from './statistics/scan/TimeRecorder'; @@ -46,6 +52,7 @@ import { USE_STATIC } from './utils/consts/InteropAPI'; import { LibraryTypeCallDiagnosticChecker } from './utils/functions/LibraryTypeCallDiagnosticChecker'; import { mergeArrayMaps } from './utils/functions/MergeArrayMaps'; import { clearPathHelperCache, pathContainsDirectory } from './utils/functions/PathHelper'; +import { processSyncErr } from './utils/functions/ProcessWrite'; function prepareInputFilesList(cmdOptions: CommandLineOptions): string[] { let inputFiles = cmdOptions.inputFiles.map((x) => { @@ -140,22 +147,37 @@ function lintFiles( TypeScriptLinter.initGlobals(); InteropTypescriptLinter.initGlobals(); let fileCount: number = 0; + const cmdProgressBar = new FixedLineProgressBar(); + const cmdProgressInfo: CmdProgressInfo = { + cmdProgressBar: cmdProgressBar, + migrationInfo: migrationInfo, + srcFiles: srcFiles, + options: options + }; + process.stderr.write('\n'); + preProcessCmdProgressBar(cmdProgressInfo); for (const srcFile of srcFiles) { const linter: BaseTypeScriptLinter = !options.interopCheckMode ? new TypeScriptLinter(tsProgram.getTypeChecker(), options, srcFile, tscStrictDiagnostics) : new InteropTypescriptLinter(tsProgram.getTypeChecker(), tsProgram.getCompilerOptions(), options, srcFile); + linter.lint(); const problems = linter.problemsInfos; problemsInfos.set(path.normalize(srcFile.fileName), [...problems]); projectStats.fileStats.push(linter.fileStats); fileCount += 1; - processProgressBar( - { migrationInfo: migrationInfo, currentSrcFile: srcFile, srcFiles: srcFiles, options: options }, - fileCount - ); + processCmdProgressBar(cmdProgressInfo, fileCount); + if (options.ideInteractive) { + processIdeProgressBar( + { migrationInfo: migrationInfo, currentSrcFile: srcFile, srcFiles: srcFiles, options: options }, + fileCount + ); + } } + postProcessCmdProgressBar(cmdProgressInfo); + return { hasErrors: projectStats.hasError(), problemsInfos, @@ -163,13 +185,9 @@ function lintFiles( }; } -function processProgressBar(progressBarInfo: ProgressBarInfo, fileCount: number): void { +export function processIdeProgressBar(progressBarInfo: ProgressBarInfo, fileCount: number): void { const { currentSrcFile, srcFiles, options } = progressBarInfo; - if (!options.ideInteractive) { - return; - } - const isMigrationStep = options.migratorMode && progressBarInfo.migrationInfo; const phasePrefix = isMigrationStep ? 'Migration Phase' : 'Scan Phase'; @@ -179,7 +197,8 @@ function processProgressBar(progressBarInfo: ProgressBarInfo, fileCount: number) const progressRatio = fileCount / srcFiles.length; const displayContent = `currentFile: ${currentSrcFile.fileName}, ${phasePrefix}${migrationPhase}`; - + process.stderr.write('\x1B[1F\x1B[0G'); + process.stderr.write('\x1B[2K'); processSyncErr( JSON.stringify({ content: displayContent, @@ -187,6 +206,7 @@ function processProgressBar(progressBarInfo: ProgressBarInfo, fileCount: number) indicator: progressRatio }) + '\n' ); + process.stderr.write('\x1B[1E'); } function migrate( @@ -235,8 +255,8 @@ function filterLinterProblemsWithAutofixConfig( problemsInfos: Map ): Map { const autofixRuleConfigTags = cmdOptions.linterOptions.autofixRuleConfigTags; - if (!cmdOptions.linterOptions.ideInteractive || !autofixRuleConfigTags) { - return problemsInfos; + if (!cmdOptions.linterOptions.ideInteractive || !autofixRuleConfigTags) { + return problemsInfos; } const needToBeFixedProblemsInfos = new Map(); @@ -284,7 +304,10 @@ function fix( let appliedFix = false; // Apply homecheck fixes first to avoid them being skipped due to conflict with linter autofixes let mergedProblems: Map = hcResults ?? new Map(); - mergedProblems = mergeArrayMaps(mergedProblems, filterLinterProblemsWithAutofixConfig(linterConfig.cmdOptions, lintResult.problemsInfos)); + mergedProblems = mergeArrayMaps( + mergedProblems, + filterLinterProblemsWithAutofixConfig(linterConfig.cmdOptions, lintResult.problemsInfos) + ); mergedProblems.forEach((problemInfos, fileName) => { const srcFile = program.getSourceFile(fileName); if (!srcFile) { diff --git a/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts b/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts new file mode 100644 index 0000000000..83518dc957 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/CmdProgressInfo.ts @@ -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. + */ + +import type * as ts from 'typescript'; +import type { LinterOptions } from '../LinterOptions'; +import type { FixedLineProgressBar } from './FixedLineProgressBar'; +import type { MigrationInfo } from './MigrationInfo'; + +export interface CmdProgressInfo { + cmdProgressBar: FixedLineProgressBar; + options: LinterOptions; + migrationInfo?: MigrationInfo; + srcFiles: ts.SourceFile[]; +} diff --git a/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts new file mode 100644 index 0000000000..4dc9be4ab6 --- /dev/null +++ b/ets2panda/linter/src/lib/progress/FixedLineProgressBar.ts @@ -0,0 +1,200 @@ +/* + * 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. + */ + +import chalk from 'chalk'; +import * as cliProgress from 'cli-progress'; +import type { CmdProgressInfo } from './CmdProgressInfo'; + +export class FixedLineProgressBar { + private readonly bar: cliProgress.SingleBar; + private currentTask: string = ''; + private currentStatus: string = ''; + private isActive = false; + private lastOutput = ''; + private static fixedLinePosition = 0; + + constructor() { + this.bar = new cliProgress.SingleBar( + { + format: (options, params, payload): string => { + const bar = options.barCompleteString!.substring(0, Math.round(params.progress * options.barsize!)); + const statusColor = + payload.status === 'scanning' ? chalk.blue : payload.status === 'fixing' ? chalk.yellow : chalk.green; + + return ( + `${chalk.bold(payload.task)} ${statusColor(payload.statusText)} [${bar}]` + + `${Math.round(params.progress * 100)}%` + ); + }, + barCompleteChar: '\u2588', + barIncompleteChar: '\u2591', + hideCursor: true, + clearOnComplete: false, + stopOnComplete: true, + linewrap: false, + forceRedraw: true, + autopadding: true, + noTTYOutput: true, + notTTYSchedule: 0 + }, + cliProgress.Presets.shades_grey + ); + } + + startBar(taskName: string, total: number, initialStatus: 'scanning' | 'fixing'): void { + this.isActive = true; + this.currentTask = taskName; + this.currentStatus = initialStatus; + + this.bar.start(total, 0, { + task: `${taskName.padEnd(12)}`, + status: initialStatus, + statusText: FixedLineProgressBar.getStatusText(initialStatus) + }); + + this.renderToFixedLine(); + } + + updateBar(progress: number, status: 'scanning' | 'fixing'): void { + if (!this.isActive) { + return; + } + + if (status !== this.currentStatus) { + this.currentStatus = status; + this.bar.update(progress, { + status, + statusText: FixedLineProgressBar.getStatusText(status) + }); + } else { + this.bar.update(progress); + } + + this.renderToFixedLine(); + } + + completeBar(): void { + if (!this.isActive) { + return; + } + + this.bar.update(this.bar.getTotal(), { + status: 'completed', + statusText: 'Completed' + }); + + this.renderToFixedLine(); + this.isActive = false; + } + + skipBar(): void { + if (!this.isActive) { + return; + } + + this.bar.update(0, { + status: 'skipped', + statusText: 'No files need to be fixed --- skipped' + }); + + this.renderToFixedLine(); + this.isActive = false; + } + + private renderToFixedLine(): void { + const content = this.bar.lastDrawnString || ''; + + FixedLineProgressBar.moveToFixedLine(); + process.stderr.write('\x1B[2K'); + process.stderr.write(content); + FixedLineProgressBar.restoreCursor(); + + this.lastOutput = content; + FixedLineProgressBar.fixedLinePosition = 1; + } + + static getStatusText(status: string): string { + const statusMap: Record = { + scanning: chalk.blue('Scanning...'), + fixing: chalk.yellow('Fixing...'), + skipped: chalk.magenta('Skipped'), + completed: chalk.green('Completed') + }; + return statusMap[status] || ''; + } + + static moveToFixedLine(): void { + const linesToMove = FixedLineProgressBar.fixedLinePosition; + if (linesToMove > 0) { + process.stderr.write(`\x1B[${linesToMove}F`); + } + process.stderr.write('\x1B[0G'); + } + + static restoreCursor(): void { + const linesToMove = FixedLineProgressBar.fixedLinePosition; + if (linesToMove > 0) { + process.stderr.write(`\x1B[${linesToMove}E`); + } + } + + stop(): void { + if (this.isActive) { + this.isActive = false; + process.stderr.write('\x1B[1F\x1B[0G\x1B[2K'); + } + } +} + +export function preProcessCmdProgressBar(cmdProgressInfo: CmdProgressInfo): void { + const { options, cmdProgressBar, srcFiles } = cmdProgressInfo; + + const isMigrationStep = options.migratorMode && cmdProgressInfo.migrationInfo; + const migrationPhase = isMigrationStep ? + ` ${cmdProgressInfo.migrationInfo!.currentPass + 1} / ${cmdProgressInfo.migrationInfo!.maxPasses}` : + ''; + const phasePrefix = isMigrationStep ? 'Migration Phase' : 'Scan Phase'; + const displayContent = `${phasePrefix}${migrationPhase}`; + const totalFiles = srcFiles.length; + + if (isMigrationStep) { + cmdProgressBar.startBar(displayContent, totalFiles, 'fixing'); + if (!srcFiles || srcFiles.length === 0) { + cmdProgressBar.skipBar(); + } + } else { + cmdProgressBar.startBar(displayContent, totalFiles, 'scanning'); + } +} + +export function processCmdProgressBar(cmdProgressInfo: CmdProgressInfo, fileCount: number): void { + const progress = fileCount; + const status = cmdProgressInfo.options.migratorMode && cmdProgressInfo.migrationInfo ? 'fixing' : 'scanning'; + + cmdProgressInfo.cmdProgressBar.updateBar(progress, status); +} + +export function postProcessCmdProgressBar(cmdProgressInfo: CmdProgressInfo): void { + const { cmdProgressBar, srcFiles } = cmdProgressInfo; + + if (srcFiles.length > 0) { + cmdProgressBar.completeBar(); + + process.stderr.write('\n'); + } else { + cmdProgressBar.skipBar(); + process.stderr.write('\n'); + } +} diff --git a/ets2panda/linter/src/lib/MigrationInfo.ts b/ets2panda/linter/src/lib/progress/MigrationInfo.ts similarity index 100% rename from ets2panda/linter/src/lib/MigrationInfo.ts rename to ets2panda/linter/src/lib/progress/MigrationInfo.ts diff --git a/ets2panda/linter/src/lib/ProgressBarInfo.ts b/ets2panda/linter/src/lib/progress/ProgressBarInfo.ts similarity index 93% rename from ets2panda/linter/src/lib/ProgressBarInfo.ts rename to ets2panda/linter/src/lib/progress/ProgressBarInfo.ts index 9a2dc34e3b..689e221588 100644 --- a/ets2panda/linter/src/lib/ProgressBarInfo.ts +++ b/ets2panda/linter/src/lib/progress/ProgressBarInfo.ts @@ -14,7 +14,7 @@ */ import type * as ts from 'typescript'; -import type { LinterOptions } from './LinterOptions'; +import type { LinterOptions } from '../LinterOptions'; import type { MigrationInfo } from './MigrationInfo'; export interface ProgressBarInfo { diff --git a/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts b/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts index 93e31a0aa5..b0bfafbcd8 100644 --- a/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts +++ b/ets2panda/linter/src/lib/statistics/scan/CountNapiFile.ts @@ -15,6 +15,7 @@ import * as fs from 'fs'; import * as path from 'path'; +import { Logger } from '../../Logger'; import type { NapiFileStatisticInfo } from './NapiFileStatisticInfo'; const EXTENSIONS = ['.c', '.cpp', '.cc', '.cxx', '.h', '.hpp', '.hh', '.hxx']; @@ -43,7 +44,7 @@ async function countLines(filePath: string): Promise { }); return validLines.length; } catch (e) { - console.error(`Error reading ${filePath}: ${e}`); + Logger.error(`Error reading ${filePath}: ${e}`); return 0; } } @@ -62,7 +63,7 @@ async function countNapiLines(filePath: string): Promise { return napiLines.size; } catch (e) { - console.error(`Error reading ${filePath}: ${e}`); + Logger.error(`Error reading ${filePath}: ${e}`); return 0; } } @@ -125,7 +126,7 @@ async function processFile(filePath: string): Promise { result.napiFileLines = lines; } } catch (e) { - console.error(`Error processing ${filePath}: ${e}`); + Logger.error(`Error processing ${filePath}: ${e}`); } return result; } @@ -140,12 +141,12 @@ export async function countNapiFiles(directory: string): Promise Date: Fri, 27 Jun 2025 13:21:05 +0200 Subject: [PATCH 022/107] Fix instanceof on this type Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIDVX Internal issue: #26927 Change-Id: Ie4a7f54f7bcda5c93ad332591718190ada34a8c9 Signed-off-by: Soma Simon --- ets2panda/parser/ETSparser.cpp | 5 +- ets2panda/parser/ETSparserTypes.cpp | 3 + ets2panda/parser/parserImpl.h | 3 +- ets2panda/public/public.cpp | 2 +- .../ets/this_type_instanceof_invalid.ets | 74 +++++++++++++++++++ 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 7b9c2399d8..dbee390278 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1870,8 +1870,9 @@ ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type [[maybe_unused]] ExpressionParseFlags flags) { if (type == lexer::TokenType::KEYW_INSTANCEOF) { - TypeAnnotationParsingOptions options = - TypeAnnotationParsingOptions::REPORT_ERROR | TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR | + TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW | + TypeAnnotationParsingOptions::INSTANCEOF; if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_NULL) { auto *typeAnnotation = AllocNode(); diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index dc590faec0..989a84d1c8 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -444,10 +444,13 @@ ir::TypeNode *ETSParser::ParseThisType(TypeAnnotationParsingOptions *options) bool parseReturnType = (*options & TypeAnnotationParsingOptions::RETURN_TYPE) != 0; bool isExtensionFunction = (GetContext().Status() & ParserStatus::HAS_RECEIVER) != 0; bool isInUnion = (*options & TypeAnnotationParsingOptions::DISALLOW_UNION) != 0; + bool isInstance = (*options & TypeAnnotationParsingOptions::INSTANCEOF) != 0; if (isExtensionFunction) { if (reportErr && (!IsSimpleReturnThis(Lexer()->GetToken()) || isInUnion)) { LogError(diagnostic::THIS_IN_NON_STATIC_METHOD, {}, startPos); } + } else if (reportErr && (isInstance)) { + LogError(diagnostic::INVALID_RIGHT_INSTANCEOF, {}, startPos); } else if (reportErr && (!allowThisType || !parseReturnType || isArrowFunc)) { LogError(diagnostic::THIS_IN_NON_STATIC_METHOD, {}, startPos); } diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 169f3c2e7f..92d471cdbc 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -63,7 +63,8 @@ enum class TypeAnnotationParsingOptions : uint32_t { ALLOW_DECLARATION_SITE_VARIANCE = 1U << 14U, DISALLOW_UNION = 1U << 15U, POTENTIAL_NEW_ARRAY = 1U << 16U, - ANNOTATION_NOT_ALLOW = 1U << 17U + ANNOTATION_NOT_ALLOW = 1U << 17U, + INSTANCEOF = 1U << 18U }; class ParserImpl { diff --git a/ets2panda/public/public.cpp b/ets2panda/public/public.cpp index 5bb8034274..c946299fed 100644 --- a/ets2panda/public/public.cpp +++ b/ets2panda/public/public.cpp @@ -56,6 +56,6 @@ void Context::MarkGenAbcForExternal(std::unordered_set &genAbcList, if (genCount != genAbcListAbsolute.size()) { diagnosticEngine->LogFatalError(diagnostic::SIMULTANEOUSLY_MARK_FAILED.Message()); } -}; +} } // namespace ark::es2panda::public_lib diff --git a/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets b/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets new file mode 100644 index 0000000000..0b96d94e59 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/this_type_instanceof_invalid.ets @@ -0,0 +1,74 @@ +/* + * 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. + */ + +type F = () => number; + +interface I { + goo(){ + if("string" instanceof this){ + return 1 + } + return 0 + } +} + +class C { + a: T; + b: F; + constructor(a: T, b: F) { + this.a = a; + this.b = b; + } + + static hoo(){ + if (5 instanceof this) { + return 0; + } + return 1; + } + + static koo(){ + if (F instanceof this) { + return 0; + } + return 1; + } + + foo() { + if (this.a instanceof this.b) { + return 0; + } + return 1; + } + + joo() { + if (G instanceof this) { + return 0; + } + return 1; + } +} + +/* @@? 20:28 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 36:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 43:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 50:27 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ +/* @@? 50:31 Error SyntaxError: Expected ')', got '.'. */ +/* @@? 50:31 Error SyntaxError: Unexpected token '.'. */ +/* @@? 50:32 Error SyntaxError: Unexpected token 'b'. */ +/* @@? 50:32 Error TypeError: Property 'b' must be accessed through 'this' */ +/* @@? 50:33 Error SyntaxError: Unexpected token ')'. */ +/* @@? 50:35 Error SyntaxError: Unexpected token '{'. */ +/* @@? 57:22 Error SyntaxError: Invalid right-hand side in 'instanceof' expression. */ -- Gitee From 652c840b085c0969bc2ad916184edb4dc6b8077f Mon Sep 17 00:00:00 2001 From: zengzengran Date: Thu, 3 Jul 2025 20:36:31 +0800 Subject: [PATCH 023/107] overload alias cannot be used in namespace Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJU54 Description: The function overload declaration ES2PANDA_ASSERT intercepts the namespace and needs to be modified. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/checker/ETSAnalyzer.cpp | 4 +- .../runtime/ets/first_match/namespace4.ets | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/first_match/namespace4.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index c4d2946155..d475fd3e1d 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -361,7 +361,9 @@ checker::Type *ETSAnalyzer::Check(ir::OverloadDeclaration *node) const } if (node->IsFunctionOverloadDeclaration()) { - ES2PANDA_ASSERT(node->Parent()->IsClassDefinition() && compiler::HasGlobalClassParent(node)); + ES2PANDA_ASSERT( + node->Parent()->IsClassDefinition() && + (compiler::HasGlobalClassParent(node) || node->Parent()->AsClassDefinition()->IsNamespaceTransformed())); checker->CheckFunctionOverloadDeclaration(checker, node); return nullptr; } diff --git a/ets2panda/test/runtime/ets/first_match/namespace4.ets b/ets2panda/test/runtime/ets/first_match/namespace4.ets new file mode 100644 index 0000000000..fd6fc43cbf --- /dev/null +++ b/ets2panda/test/runtime/ets/first_match/namespace4.ets @@ -0,0 +1,40 @@ +/* + * 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 overload foo{ foo1, foo2 }; + export function foo1(a: number): string { + return "invoke1" + } + export function foo2(a: string): string { + return "invoke2" + } + export namespace NS2 { + export overload foo{ foo1, foo2 }; + export function foo1(a: number): string { + return "invoke3" + } + export function foo2(a: string): string { + return "invoke4" + } + } +} + +function main() { + arktest.assertEQ(NS.foo(1), "invoke1") + arktest.assertEQ(NS.foo("abc"), "invoke2") + arktest.assertEQ(NS.NS2.foo(1), "invoke3") + arktest.assertEQ(NS.NS2.foo("abc"), "invoke4") +} -- Gitee From ce808fce5db60c35e656d86e9ea41add14fa70e3 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Thu, 3 Jul 2025 20:54:07 +0800 Subject: [PATCH 024/107] fix smart cast bug Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJU9E?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ETSAnalyzer.cpp | 2 +- .../ets/defaultParametersLowering.cpp | 3 + .../test/ast/compiler/ets/smart_cast.ets | 28 ++++ .../ets/default_parameter5-expected.txt | 72 ++++----- .../ets/default_parameter7-expected.txt | 72 ++++----- ..._implicitly_typed_return_void-expected.txt | 144 +++++++++--------- .../ets/proxyVoidGeneration-expected.txt | 96 ++++++------ .../parser/ets/rest_parameter_02-expected.txt | 72 ++++----- 8 files changed, 260 insertions(+), 229 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/smart_cast.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index c4d2946155..b15d9a5313 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1770,7 +1770,7 @@ checker::Type *ETSAnalyzer::Check(ir::ConditionalExpression *expr) const checker->Context().CombineSmartCasts(consequentSmartCasts); if (checker->IsTypeIdenticalTo(consequentType, alternateType)) { - expr->SetTsType(checker->GetNonConstantType(consequentType)); + expr->SetTsType(consequentType); } else if (IsNumericType(GetETSChecker(), consequentType) && IsNumericType(GetETSChecker(), alternateType)) { expr->SetTsType(BiggerNumericType(GetETSChecker(), consequentType, alternateType)); } else { diff --git a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp index e6bffbeee3..dd3fe91cd7 100644 --- a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp @@ -65,6 +65,9 @@ static void TransformDefaultParameters(public_lib::Context *ctx, ir::ScriptFunct auto const param = params.at(dfltIdx); auto stmt = TransformInitializer(allocator, parser, param); bodyStmt[dfltIdx] = stmt; + // From a developer's perspective, this locational information is more intuitive. + stmt->SetParent(param); + RefineSourceRanges(stmt); stmt->SetParent(body); } } diff --git a/ets2panda/test/ast/compiler/ets/smart_cast.ets b/ets2panda/test/ast/compiler/ets/smart_cast.ets new file mode 100644 index 0000000000..226a7a068e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/smart_cast.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. + */ + +function foo(p: "Object" | "String" | "Number" = "Object") { // should be ok +} + +function bar(p: "Object") { + let s: "Object" = p != undefined ? p : "Object"// should be ok +} + +function baz(p: "Double") { + let s: "Object" = p != undefined ? p : "Double"// should be cte +} + +/* @@? 24:23 Error TypeError: Type '"Double"' cannot be assigned to type '"Object"' */ + diff --git a/ets2panda/test/parser/ets/default_parameter5-expected.txt b/ets2panda/test/parser/ets/default_parameter5-expected.txt index ce56595f02..f4ea3eb503 100644 --- a/ets2panda/test/parser/ets/default_parameter5-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter5-expected.txt @@ -591,14 +591,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 35, + "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 55, + "program": "default_parameter5.ets" } } }, @@ -607,26 +607,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } @@ -637,14 +637,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 35, + "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 55, + "program": "default_parameter5.ets" } } }, @@ -734,39 +734,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } @@ -775,13 +775,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 21, + "column": 35, "program": "default_parameter5.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 55, "program": "default_parameter5.ets" } } diff --git a/ets2panda/test/parser/ets/default_parameter7-expected.txt b/ets2panda/test/parser/ets/default_parameter7-expected.txt index 3a86fd3bd3..36fee45087 100644 --- a/ets2panda/test/parser/ets/default_parameter7-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter7-expected.txt @@ -983,14 +983,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 36, + "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 48, + "program": "default_parameter7.ets" } } }, @@ -999,26 +999,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } @@ -1029,14 +1029,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 36, + "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 21, + "column": 48, + "program": "default_parameter7.ets" } } }, @@ -1107,39 +1107,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } @@ -1148,13 +1148,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 21, + "column": 36, "program": "default_parameter7.ets" }, "end": { - "line": 1, - "column": 3, + "line": 21, + "column": 48, "program": "default_parameter7.ets" } } diff --git a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt index 1115ac77c6..e4aaaa7a48 100644 --- a/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt +++ b/ets2panda/test/parser/ets/default_parameter_implicitly_typed_return_void-expected.txt @@ -500,14 +500,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 25, + "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 47, + "program": "default_parameter_implicitly_typed_return_void.ets" } } }, @@ -516,26 +516,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } @@ -546,14 +546,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 25, + "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 47, + "program": "default_parameter_implicitly_typed_return_void.ets" } } }, @@ -624,39 +624,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } @@ -665,13 +665,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 16, + "column": 25, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 47, "program": "default_parameter_implicitly_typed_return_void.ets" } } @@ -756,14 +756,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 49, + "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 70, + "program": "default_parameter_implicitly_typed_return_void.ets" } } }, @@ -772,26 +772,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } @@ -802,14 +802,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 49, + "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 16, + "column": 70, + "program": "default_parameter_implicitly_typed_return_void.ets" } } }, @@ -880,39 +880,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } @@ -921,13 +921,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 16, + "column": 49, "program": "default_parameter_implicitly_typed_return_void.ets" }, "end": { - "line": 1, - "column": 3, + "line": 16, + "column": 70, "program": "default_parameter_implicitly_typed_return_void.ets" } } diff --git a/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt b/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt index 91269d01ca..8e802f9dc0 100644 --- a/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt +++ b/ets2panda/test/parser/ets/proxyVoidGeneration-expected.txt @@ -265,14 +265,14 @@ "type": "ETSNullType", "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 16, + "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 28, + "program": "proxyVoidGeneration.ets" } } } @@ -315,14 +315,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 10, + "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 35, + "program": "proxyVoidGeneration.ets" } } }, @@ -331,26 +331,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } @@ -361,14 +361,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 10, + "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 35, + "program": "proxyVoidGeneration.ets" } } }, @@ -444,14 +444,14 @@ "type": "ETSNullType", "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 16, + "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 17, + "column": 28, + "program": "proxyVoidGeneration.ets" } } } @@ -471,39 +471,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } @@ -512,13 +512,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 17, + "column": 10, "program": "proxyVoidGeneration.ets" }, "end": { - "line": 1, - "column": 3, + "line": 17, + "column": 35, "program": "proxyVoidGeneration.ets" } } diff --git a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt index 3a9949c0ee..50c4c4b766 100644 --- a/ets2panda/test/parser/ets/rest_parameter_02-expected.txt +++ b/ets2panda/test/parser/ets/rest_parameter_02-expected.txt @@ -806,14 +806,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 20, + "column": 31, + "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 20, + "column": 41, + "program": "rest_parameter_02.ets" } } }, @@ -822,26 +822,26 @@ "value": "undefined", "loc": { "start": { - "line": 1, - "column": 3, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } @@ -852,14 +852,14 @@ "decorators": [], "loc": { "start": { - "line": 1, - "column": 1, - "program": null + "line": 20, + "column": 31, + "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 1, - "program": null + "line": 20, + "column": 41, + "program": "rest_parameter_02.ets" } } }, @@ -898,39 +898,39 @@ }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } }, "loc": { "start": { - "line": 1, - "column": 3, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } @@ -939,13 +939,13 @@ "kind": "let", "loc": { "start": { - "line": 1, - "column": 1, + "line": 20, + "column": 31, "program": "rest_parameter_02.ets" }, "end": { - "line": 1, - "column": 3, + "line": 20, + "column": 41, "program": "rest_parameter_02.ets" } } -- Gitee From d2fe14de7c18eab8767fafa1ce29faec7e77b1b8 Mon Sep 17 00:00:00 2001 From: daizihan Date: Wed, 2 Jul 2025 15:34:14 +0800 Subject: [PATCH 025/107] Fix lamda type infer Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJG95?from=project-issue Signed-off-by: daizihan --- ets2panda/checker/ets/typeCheckingHelpers.cpp | 10 +++--- .../test/runtime/ets/lambda_union_infer.ets | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 ets2panda/test/runtime/ets/lambda_union_infer.ets diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index f2a5fd239c..82bbbc5041 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -1423,7 +1423,6 @@ bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction // the surrounding function is made so we can *bypass* the typecheck in the "inference" context, // however the body of the function has to be checked in any case if (typeAnn->IsETSUnionType()) { - lambda->Parent()->Check(this); return CheckLambdaAssignableUnion(typeAnn, lambda); } @@ -1492,13 +1491,12 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::ETSParameterExpression *param, } auto *const lambdaReturnTypeAnnotation = lambda->ReturnTypeAnnotation(); - Type *const argumentType = arrowFuncExpr->Check(this); - if (Relation()->IsSupertypeOf(parameterType, argumentType)) { - return true; + if (!parameterType->IsETSUnionType() || parameterType->AsETSUnionType()->ConstituentTypes().size() != + typeAnnotation->AsETSUnionType()->Types().size()) { + Type *const argumentType = arrowFuncExpr->Check(this); + return Relation()->IsSupertypeOf(parameterType, argumentType); } - ES2PANDA_ASSERT(parameterType->AsETSUnionType()->ConstituentTypes().size() == - typeAnnotation->AsETSUnionType()->Types().size()); const auto typeAnnsOfUnion = typeAnnotation->AsETSUnionType()->Types(); const auto typeParamOfUnion = parameterType->AsETSUnionType()->ConstituentTypes(); for (size_t ix = 0; ix < typeAnnsOfUnion.size(); ++ix) { diff --git a/ets2panda/test/runtime/ets/lambda_union_infer.ets b/ets2panda/test/runtime/ets/lambda_union_infer.ets new file mode 100644 index 0000000000..d9ffa84722 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambda_union_infer.ets @@ -0,0 +1,35 @@ + +/* + * 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. + */ + +export interface RA { + each: ()=> void +} + +export function Repeat(style: ((instance: RA) => void) | undefined) { + if (style != undefined) { + let a : RA = { each: ()=>{} } + style(a); + } +} + +function main() { + let count = 0; + Repeat((instance) => { + instance.each() + count++; + }); + arktest.assertEQ(count, 1) +} -- Gitee From a5ebc6572bd877a882c7646b0618524c33fd733e Mon Sep 17 00:00:00 2001 From: tengtengh Date: Thu, 3 Jul 2025 22:17:15 +0800 Subject: [PATCH 026/107] Fix interface generic method as value Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJUIR Signed-off-by: tengtengh --- .../compiler/lowering/ets/lambdaLowering.cpp | 20 +++++++++--- .../ets/interface_method_as_value_1.ets | 26 ++++++++++++++++ .../ets/interface_method_as_value_3.ets | 31 +++++++++++++++++++ 3 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets create mode 100644 ets2panda/test/runtime/ets/interface_method_as_value_3.ets diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index 17cfcc6a9a..c900443423 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -32,6 +32,7 @@ struct LambdaInfo { ArenaSet *capturedVars = nullptr; ir::Expression *callReceiver = nullptr; bool isFunctionReference = false; + checker::ETSObjectType *objType = nullptr; }; struct CalleeMethodInfo { @@ -432,8 +433,10 @@ static void CreateLambdaClassFields(public_lib::Context *ctx, ir::ClassDefinitio auto *checker = ctx->GetChecker()->AsETSChecker(); auto props = ArenaVector(allocator->Adapter()); - checker::Type *objectType = - info->calleeClass != nullptr ? info->calleeClass->Definition()->TsType() : info->calleeInterface->TsType(); + checker::Type *objectType = info->objType != nullptr + ? info->objType + : (info->calleeClass != nullptr ? info->calleeClass->Definition()->TsType() + : info->calleeInterface->TsType()); if (info->callReceiver != nullptr) { auto *outerThisDeclaration = parser->CreateFormattedClassFieldDefinition( @@ -467,8 +470,10 @@ static void CreateLambdaClassConstructor(public_lib::Context *ctx, ir::ClassDefi params.push_back(param); }; - checker::Type *objectType = - info->calleeClass != nullptr ? info->calleeClass->Definition()->TsType() : info->calleeInterface->TsType(); + checker::Type *objectType = info->objType != nullptr + ? info->objType + : (info->calleeClass != nullptr ? info->calleeClass->Definition()->TsType() + : info->calleeInterface->TsType()); if (info->callReceiver != nullptr) { makeParam("$this", objectType); @@ -1091,6 +1096,9 @@ static LambdaInfo GenerateLambdaInfoForFunctionReference(public_lib::Context *ct ES2PANDA_ASSERT(funcRef->IsMemberExpression()); info.callReceiver = funcRef->AsMemberExpression()->Object(); } + if (funcRef->IsMemberExpression()) { + info.objType = funcRef->AsMemberExpression()->ObjType(); + } return info; } @@ -1135,7 +1143,9 @@ static ir::AstNode *ConvertFunctionReference(public_lib::Context *ctx, ir::Expre ES2PANDA_ASSERT(funcRef->TsType()->IsETSArrowType()); auto *lambdaClass = CreateLambdaClass(ctx, funcRef->TsType()->AsETSFunctionType(), method, &info); auto *constructorCall = CreateConstructorCall(ctx, funcRef, lambdaClass, &info); - constructorCall->TsType()->AsETSObjectType()->AddObjectFlag(checker::ETSObjectFlags::FUNCTIONAL_REFERENCE); + if (constructorCall->TsType()->IsETSObjectType()) { + constructorCall->TsType()->AsETSObjectType()->AddObjectFlag(checker::ETSObjectFlags::FUNCTIONAL_REFERENCE); + } return constructorCall; } diff --git a/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets b/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.ets new file mode 100644 index 0000000000..3e1f2336bc --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_method_as_value_1.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. + */ + +declare function g(a: string): void; +let gg: (a: string)=>void = g; + +interface Obj { + method(value: T): void; +} + +declare const o1: Obj; + +gg = o1.method; + diff --git a/ets2panda/test/runtime/ets/interface_method_as_value_3.ets b/ets2panda/test/runtime/ets/interface_method_as_value_3.ets new file mode 100644 index 0000000000..65fed84965 --- /dev/null +++ b/ets2panda/test/runtime/ets/interface_method_as_value_3.ets @@ -0,0 +1,31 @@ +/* + * 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. + */ + + +let gg: (a: string)=>void; + +class Obj { + method2 = (value:T):void => {} + method(value: T): void {}; +} + +class Obj2 { + method(): void {} +} + +function foo(o: Obj, o2: Obj2) { + gg = o2.method; + gg = o.method; +} -- Gitee From 398caddeaf728397fe86e280d9eb183303898579 Mon Sep 17 00:00:00 2001 From: suruifeng Date: Wed, 2 Jul 2025 10:16:33 +0800 Subject: [PATCH 027/107] [runtime] ignore namespace ets Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJBQ5 Signed-off-by: suruifeng --- .../test/test-lists/ets-runtime/ets-runtime-ignored.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 1d93b6ed84..008c22e9c0 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -119,4 +119,7 @@ Recursive_Parameter_3.ets # No-primitives #24986 [end] # 27159 Recursive type alias with generics -RecursiveTypeAlias10.ets \ No newline at end of file +RecursiveTypeAlias10.ets +first_match/namespace.ets +first_match/namespace2.ets +first_match/namespace3.ets -- Gitee From dd7f5161affa9781905b7745de8d2107d7442957 Mon Sep 17 00:00:00 2001 From: Denis Silakov Date: Fri, 4 Jul 2025 11:57:28 +0300 Subject: [PATCH 028/107] Update codecheck ignore file for linter Codecheck is sometimes confused by Issue: #ICJUIQ Testing: all internal tests passed Signed-off-by: Denis Silakov --- codecheck_ignore.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/codecheck_ignore.json b/codecheck_ignore.json index e51d43f3b4..a30bb19d2b 100755 --- a/codecheck_ignore.json +++ b/codecheck_ignore.json @@ -14,7 +14,9 @@ "ets2panda/linter/arkanalyzer": "*", "ets2panda/linter/homecheck": "*", "ets2panda/linter/build_linter.py": "*", + "ets2panda/linter/src/cli/CommandLineParser.ts": "*", "ets2panda/linter/src/lib/TypeScriptLinter.ts": "*", + "ets2panda/linter/src/lib/autofixes/Autofixer.ts": "*", "ets2panda/linter/src/lib/autofixes/QuasiEditor.ts": "*", "ets2panda/linter/src/lib/statistics/scan/ProblemStatisticsCommonFunction.ts": "*", "ets2panda/linter/src/lib/utils/functions/ConfiguredRulesProcess.ts": "*", -- Gitee From 4c2e1765f840ead38c7be60307c766fdd29eb68a Mon Sep 17 00:00:00 2001 From: lijunru Date: Mon, 30 Jun 2025 21:14:15 +0800 Subject: [PATCH 029/107] Enable bindings test Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIY4T Signed-off-by: lijunru --- bundle.json | 5 +- ets2panda/bindings/test/BUILD.gn | 25 +++++++ ets2panda/bindings/test/cases.ts | 4 + .../test/expected/getSemanticDiagnostics.json | 6 +- .../expected/getSyntacticDiagnostics.json | 34 ++++----- ets2panda/bindings/test/monitor_node.js | 48 ++++++++++++ ets2panda/bindings/test/run_bindings.sh | 40 ++++++++++ ets2panda/bindings/test/run_tests.ts | 45 +++++++++-- .../bindings/test/testcases/entry/Index.ets | 74 +++++++++++++++++++ 9 files changed, 254 insertions(+), 27 deletions(-) create mode 100644 ets2panda/bindings/test/BUILD.gn create mode 100644 ets2panda/bindings/test/monitor_node.js create mode 100755 ets2panda/bindings/test/run_bindings.sh create mode 100644 ets2panda/bindings/test/testcases/entry/Index.ets diff --git a/bundle.json b/bundle.json index 142291a602..0029c20177 100644 --- a/bundle.json +++ b/bundle.json @@ -48,8 +48,9 @@ } ], "test": [ - "//arkcompiler/ets_frontend/es2panda:es2abc_tests" + "//arkcompiler/ets_frontend/es2panda:es2abc_tests", + "//arkcompiler/ets_frontend/ets2panda/bindings/test:bindings_test" ] } } -} +} \ No newline at end of file diff --git a/ets2panda/bindings/test/BUILD.gn b/ets2panda/bindings/test/BUILD.gn new file mode 100644 index 0000000000..83a299be12 --- /dev/null +++ b/ets2panda/bindings/test/BUILD.gn @@ -0,0 +1,25 @@ +# 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. + +import("//build/version.gni") + +action("bindings_test") { + script = "run_bindings.sh" + args = [ + rebase_path("./"), + rebase_path( + "//prebuilts/build-tools/common/nodejs/node-v16.20.2-linux-x64/bin"), + rebase_path("//prebuilts/ohos-sdk/linux/${api_version}/ets"), + ] + outputs = [ "$target_out_dir/$target_name.timestamp" ] +} diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts index f353848c71..9d00420987 100644 --- a/ets2panda/bindings/test/cases.ts +++ b/ets2panda/bindings/test/cases.ts @@ -145,6 +145,10 @@ export const testCases: TestCases = { getRenameInfo: { expectedFilePath: resolveTestPath('test/expected/getRenameInfo.json'), '1': [resolveTestPath('test/testcases/getRenameInfo/getRenameInfo1.ets'), 615] + }, + entry: { + expectedFilePath: '', + '1': [resolveTestPath('test/testcases/entry/Index.ets'), 615] } }; diff --git a/ets2panda/bindings/test/expected/getSemanticDiagnostics.json b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json index 8c5983e344..96a6551b8d 100644 --- a/ets2panda/bindings/test/expected/getSemanticDiagnostics.json +++ b/ets2panda/bindings/test/expected/getSemanticDiagnostics.json @@ -19,7 +19,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2046, "data": 0, "severity": 1, "codeDescription": { @@ -41,7 +41,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2127, "data": 0, "severity": 1, "codeDescription": { @@ -63,7 +63,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 2318, "data": 0, "severity": 1, "codeDescription": { diff --git a/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json index baa3c0c3ad..37ff72da0f 100644 --- a/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json +++ b/ets2panda/bindings/test/expected/getSyntacticDiagnostics.json @@ -19,7 +19,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -41,7 +41,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1229, "data": 0, "severity": 1, "codeDescription": { @@ -63,7 +63,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -85,7 +85,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -107,7 +107,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -129,7 +129,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -151,7 +151,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -160,20 +160,20 @@ }, { "message": "Unexpected token 'b'.", - "source": "", + "source": "functon;\nadd(a);\n*ERROR_LITERAL*;\nnumber;\n*ERROR_LITERAL*;\n\nnumber;\n*ERROR_LITERAL*;\n{\n return ((a) + (b));\n}\nn = 333;\nres = add(n, n);", "range": { "start": { "line": 16, - "character": 24 + "character": 1 }, "end": { - "line": 16, - "character": 24 + "line": 20, + "character": 20 } }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -195,7 +195,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1038, "data": 0, "severity": 1, "codeDescription": { @@ -217,7 +217,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -239,7 +239,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -261,7 +261,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1227, "data": 0, "severity": 1, "codeDescription": { @@ -283,7 +283,7 @@ }, "tags": [], "relatedInfo": [], - "code": 1, + "code": 1163, "data": 0, "severity": 1, "codeDescription": { diff --git a/ets2panda/bindings/test/monitor_node.js b/ets2panda/bindings/test/monitor_node.js new file mode 100644 index 0000000000..aade7588cf --- /dev/null +++ b/ets2panda/bindings/test/monitor_node.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +/* + * 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. + */ + +const { spawn } = require('child_process'); + +const child = spawn(process.argv[2], process.argv.slice(3), { + stdio: 'inherit', + detached: true, + windowsHide: true +}); + +const timeout = setTimeout(() => { + console.error('process timeout'); + child.kill('SIGKILL'); + process.exit(124); +}, 900000); + +child.on('exit', (code, signal) => { + clearTimeout(timeout); + + if (signal === 'SIGSEGV' || signal === 'SIGABRT') { + console.error(`process crashe: ${signal}`); + process.exit(128 + signal); + } else { + process.exit(code ?? 0); + } +}); + +child.on('error', (err) => { + clearTimeout(timeout); + console.error(`Promoter process failure: ${err.message}`); + process.exit(127); +}); + +child.unref(); \ No newline at end of file diff --git a/ets2panda/bindings/test/run_bindings.sh b/ets2panda/bindings/test/run_bindings.sh new file mode 100755 index 0000000000..7fef1f2f16 --- /dev/null +++ b/ets2panda/bindings/test/run_bindings.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# 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. + +set -e + +readonly TEST_DIR="$1" +readonly NODE_DIR="$2" +readonly SDK_DIR="$3" +readonly CWD="${TEST_DIR}/../" +readonly CURRENT_NPM="${NODE_DIR}/npm" +readonly CURRENT_NODE="${NODE_DIR}/node" + +cp -rfp -- "$SDK_DIR" "$TEST_DIR" +cd "$CWD" && "$CURRENT_NPM" run test:build +if [ $? -eq 0 ]; then + echo "bindings test build successfully" +else + echo "bindings test build failed" + exit 1 +fi + +"$CURRENT_NODE" test/monitor_node.js "$CURRENT_NODE" --unhandled-rejections=strict dist-test/test/run_tests.js ./test +exit_code=$? +if [ $exit_code -eq 0 ]; then + echo "test execution successfully" +else + echo "test execution failed" + exit $exit_code +fi diff --git a/ets2panda/bindings/test/run_tests.ts b/ets2panda/bindings/test/run_tests.ts index 9220c53c91..f2513ab806 100644 --- a/ets2panda/bindings/test/run_tests.ts +++ b/ets2panda/bindings/test/run_tests.ts @@ -292,11 +292,11 @@ function compareResults(testName: string, index: string, actual: unknown, expect return compareResultsHelper(name, normalizeData(actual), expected); } -function runTests(testDir: string, lsp: Lsp) { +function runTests(lsp: Lsp): boolean { console.log('Running tests...'); if (!testCases) { console.error('Failed to load test cases'); - return; + return false; } let failedList: string[] = []; @@ -344,9 +344,32 @@ function runTests(testDir: string, lsp: Lsp) { failedList.forEach((failedCase) => { console.log(`- ${failedCase}`); }); + return false; + } else { + return true; } } +function run(lsp: Lsp) { + const res = runTests(lsp); + if (!res) { + console.error('Tests failed without AST cache'); + process.exit(1); + } + console.log('Finished test without ast cache'); +} + +async function runWithAstCache(lsp: Lsp, modules: ModuleDescriptor[]): Promise { + await lsp.initAstCache(); + lsp.update(modules); + const res = runTests(lsp); + if (!res) { + console.error('Tests failed with AST cache'); + process.exit(1); + } + console.log('Finished test with ast cache'); +} + if (require.main === module) { if (process.argv.length < 3) { console.error('Usage: node run_tests.js '); @@ -364,9 +387,21 @@ if (require.main === module) { }; const modules = getModules(pathConfig.projectPath); - + process.env.BINDINGS_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'bindings'); + process.env.PANDA_LIB_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'ets2panda', 'lib'); + process.env.PANDA_BIN_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'ets2panda', 'bin'); const lsp = new Lsp(pathConfig, undefined, modules); + run(lsp); - process.env.BINDINGS_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'bindings'); - runTests(testDir, lsp); + // for generate ast cache + const entry_module = [ + { + arktsversion: '1.2', + name: 'entry', + moduleType: 'har', + srcPath: path.join(pathConfig.projectPath, 'entry') + } + ]; + const lsp_1 = new Lsp(pathConfig, undefined, entry_module); + runWithAstCache(lsp_1, modules).then(() => {}); } diff --git a/ets2panda/bindings/test/testcases/entry/Index.ets b/ets2panda/bindings/test/testcases/entry/Index.ets new file mode 100644 index 0000000000..a665975076 --- /dev/null +++ b/ets2panda/bindings/test/testcases/entry/Index.ets @@ -0,0 +1,74 @@ +/* + * 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. + */ + +import { Text, Column, Component, Entry, Button, ClickEvent } from "@ohos.arkui.component" +import { State, Link, Prop } from "@ohos.arkui.stateManagement" +import hilog from '@ohos.hilog' + +@Entry +@Component +struct MyStateSample { + @State stateVar: string = "state var"; + message: string = `click to change state variable, add **`; + changeValue() { + this.stateVar+="**" + } + build() { + Column() { + Button("clean variable").onClick((e: ClickEvent) => { this.stateVar = "state var" }) + Text("Hello World").fontSize(20) + Button(this.message).backgroundColor("#FFFF00FF") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue() + }) + Text(this.stateVar).fontSize(20) + Child({linkVar: this.stateVar, propVar: this.stateVar}) + }.margin(10) + } +} + +@Component +struct Child { + @Link linkVar: string = ""; // TODO: remove this + @Prop propVar: string = "Prop"; + + changeValue1() { + this.linkVar+="!!" + } + + changeValue2() { + this.propVar+="~~" + } + + build() { + Column() { + Button(`click to change Link variable, add symbol !!`) + .backgroundColor("#4169E1") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue1() + }) + Button(`click to change Prop variable, add symbol ~~`) + .backgroundColor("#3CB371") + .onClick((e: ClickEvent) => { + hilog.info(0x0000, 'testTag', 'On Click'); + this.changeValue2() + }) + Text(`Link variable in child: ${this.linkVar}`).fontSize(30) + Text(`Prop variable in child: ${this.propVar}`).fontSize(30) + } + } +} \ No newline at end of file -- Gitee From f5097448181df0a2a8584814acbccf0f686f22c9 Mon Sep 17 00:00:00 2001 From: tsatsulya Date: Tue, 1 Jul 2025 12:47:33 +0300 Subject: [PATCH 030/107] fix codecheck Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJ8VC Signed-off-by: tsatsulya --- ets2panda/compiler/base/lreference.cpp | 5 ++++- ets2panda/compiler/core/CFG.cpp | 4 ++++ ets2panda/compiler/core/ETSCompiler.cpp | 5 +++++ ets2panda/compiler/core/ETSemitter.cpp | 12 ++++++++++++ ets2panda/compiler/core/JSCompiler.cpp | 3 ++- ets2panda/compiler/core/dynamicContext.cpp | 3 +++ ets2panda/compiler/core/moduleContext.cpp | 1 + ets2panda/compiler/core/pandagen.cpp | 1 + ets2panda/compiler/core/regAllocator.cpp | 2 ++ ets2panda/compiler/lowering/ets/ambientLowering.cpp | 1 + .../compiler/lowering/ets/arrayLiteralLowering.cpp | 3 +++ .../compiler/lowering/ets/asyncMethodLowering.cpp | 6 +++++- ets2panda/compiler/lowering/ets/boxingForLocals.cpp | 4 ++++ .../debugInfoDeserializer.cpp | 4 +++- .../debugInfoDeserialization/methodBuilder.cpp | 3 +++ ets2panda/evaluate/helpers.cpp | 2 +- ets2panda/evaluate/scopedDebugInfoPlugin.cpp | 2 ++ ets2panda/ir/base/catchClause.cpp | 11 +++++++++-- ets2panda/ir/base/decorator.cpp | 1 + ets2panda/ir/base/metaProperty.cpp | 1 + ets2panda/ir/base/methodDefinition.cpp | 3 ++- ets2panda/ir/base/methodDefinition.h | 1 + ets2panda/ir/base/property.cpp | 1 + ets2panda/ir/base/scriptFunction.cpp | 1 + ets2panda/ir/base/spreadElement.cpp | 1 + ets2panda/ir/base/templateElement.cpp | 1 + ets2panda/ir/base/tsIndexSignature.cpp | 1 + ets2panda/ir/base/tsPropertySignature.cpp | 1 + ets2panda/ir/expressions/callExpression.cpp | 1 + ets2panda/ir/expressions/chainExpression.cpp | 1 + ets2panda/ir/expressions/classExpression.cpp | 1 + ets2panda/ir/expressions/functionExpression.cpp | 2 ++ ets2panda/ir/expressions/identifier.cpp | 2 ++ ets2panda/ir/expressions/importExpression.cpp | 1 + ets2panda/ir/expressions/literals/bigIntLiteral.cpp | 1 + .../ir/expressions/literals/booleanLiteral.cpp | 1 + ets2panda/ir/expressions/literals/charLiteral.cpp | 1 + ets2panda/ir/expressions/literals/nullLiteral.cpp | 1 + ets2panda/ir/expressions/literals/numberLiteral.cpp | 5 +++-- ets2panda/ir/expressions/literals/regExpLiteral.cpp | 1 + ets2panda/ir/expressions/literals/stringLiteral.cpp | 1 + .../ir/expressions/literals/undefinedLiteral.cpp | 1 + ets2panda/ir/expressions/memberExpression.cpp | 3 +++ ets2panda/ir/expressions/newExpression.cpp | 1 + ets2panda/ir/expressions/objectExpression.cpp | 2 ++ ets2panda/ir/expressions/omittedExpression.cpp | 1 + ets2panda/ir/expressions/sequenceExpression.cpp | 1 + ets2panda/ir/expressions/superExpression.cpp | 1 + .../ir/expressions/taggedTemplateExpression.cpp | 1 + ets2panda/ir/expressions/templateLiteral.cpp | 1 + ets2panda/ir/expressions/thisExpression.cpp | 1 + ets2panda/ir/expressions/unaryExpression.cpp | 1 + ets2panda/ir/expressions/updateExpression.cpp | 1 + ets2panda/ir/expressions/yieldExpression.cpp | 1 + ets2panda/ir/ts/tsArrayType.cpp | 1 + ets2panda/ir/ts/tsAsExpression.cpp | 1 + ets2panda/ir/ts/tsQualifiedName.cpp | 1 + ets2panda/ir/ts/tsThisType.cpp | 1 + ets2panda/ir/ts/tsTupleType.cpp | 13 +++++++++---- ets2panda/ir/ts/tsTypeLiteral.cpp | 1 + ets2panda/ir/ts/tsTypeParameterDeclaration.h | 1 + ets2panda/ir/typeNode.cpp | 1 + 62 files changed, 125 insertions(+), 14 deletions(-) diff --git a/ets2panda/compiler/base/lreference.cpp b/ets2panda/compiler/base/lreference.cpp index ca4f4e6652..1ae778a945 100644 --- a/ets2panda/compiler/base/lreference.cpp +++ b/ets2panda/compiler/base/lreference.cpp @@ -306,6 +306,7 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *memberExpr) con if (objectType->IsETSArrayType() || objectType->IsETSResizableArrayType()) { auto vRegtype = etsg_->GetVRegType(baseReg_); + ES2PANDA_ASSERT(vRegtype != nullptr); auto *elementType = vRegtype->IsETSArrayType() ? vRegtype->AsETSArrayType()->ElementType() : vRegtype->AsETSResizableArrayType()->ElementType(); etsg_->StoreArrayElement(Node(), baseReg_, propReg_, elementType); @@ -317,11 +318,12 @@ void ETSLReference::SetValueComputed(const ir::MemberExpression *memberExpr) con void ETSLReference::SetValueGetterSetter(const ir::MemberExpression *memberExpr) const { + ES2PANDA_ASSERT(memberExpr->PropVar() != nullptr); const auto *sig = memberExpr->PropVar()->TsType()->AsETSFunctionType()->FindSetter(); auto argReg = etsg_->AllocReg(); etsg_->StoreAccumulator(Node(), argReg); - + ES2PANDA_ASSERT(sig->Function() != nullptr); if (sig->Function()->IsStatic()) { etsg_->CallExact(Node(), sig->InternalName(), argReg); } else if (memberExpr->Object()->IsSuperExpression()) { @@ -356,6 +358,7 @@ void ETSLReference::SetValue() const return; } + ES2PANDA_ASSERT(memberExpr->PropVar() != nullptr); if (memberExpr->PropVar()->TsType()->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { SetValueGetterSetter(memberExpr); return; diff --git a/ets2panda/compiler/core/CFG.cpp b/ets2panda/compiler/core/CFG.cpp index cfafe5d792..d1e62215e0 100644 --- a/ets2panda/compiler/core/CFG.cpp +++ b/ets2panda/compiler/core/CFG.cpp @@ -32,6 +32,7 @@ size_t CFG::BasicBlock::AddNode(ir::AstNode *node) std::pair CFG::BasicBlock::AddSuccessor(BasicBlock *successor) { + ES2PANDA_ASSERT(successor != nullptr); succs_.push_back(successor); successor->preds_.push_back(this); return std::make_pair(succs_.size() - 1, successor->preds_.size() - 1); @@ -208,6 +209,7 @@ CFG::BasicBlock *CFG::Build(ir::ScriptFunction *scriptFunctionNode) } ES2PANDA_ASSERT(scriptFunctionNode->Body()->IsBlockStatement()); auto exitBB = Build(scriptFunctionNode->Body()->AsBlockStatement(), entryBB); + ES2PANDA_ASSERT(exitBB != nullptr); exitBB->SetFlag(BasicBlockFlags::EXIT); return entryBB; } @@ -231,6 +233,7 @@ CFG::BasicBlock *CFG::CreateNewBB(const std::vector &&preds, const std::vector &&labels) { auto bb = allocator_->New(allocator_, basicBlockIdx_++); + ES2PANDA_ASSERT(bb != nullptr); if (inLoop_ > 0) { bb->SetFlag(BasicBlockFlags::LOOP); } @@ -840,6 +843,7 @@ size_t CFG::AddNodeToBB(ir::AstNode *node, BasicBlock *bb) if (bb == nullptr) { bb = CreateNewBB({}); } + ES2PANDA_ASSERT(bb != nullptr); size_t index = bb->AddNode(node); nodeBBMap_[node] = std::make_pair(bb, index); return index; diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 8992e44632..15549ccb50 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -174,6 +174,7 @@ static void ConvertRestArguments(checker::ETSChecker *const checker, const ir::E elements.emplace_back(expr->GetArguments()[i]); } auto *arrayExpression = checker->AllocNode(std::move(elements), checker->Allocator()); + ES2PANDA_ASSERT(arrayExpression != nullptr); arrayExpression->SetParent(const_cast(expr)); auto restType = expr->GetSignature()->RestVar()->TsType()->AsETSArrayType(); arrayExpression->SetTsType(restType); @@ -735,6 +736,7 @@ void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calle // NOTE: need to refactor: type of member expression object can be obtained via // me->ObjType() or me->Object()->TsType() and they may differ!!!! } else if (me->ObjType() == etsg->Checker()->GlobalETSObjectType() && + (etsg->Checker()->GetApparentType(me->Object()->TsType()) != nullptr) && (etsg->Checker()->GetApparentType(me->Object()->TsType())->IsETSUnionType())) { etsg->CallByName(expr, signature, calleeReg, expr->Arguments()); } else { @@ -939,6 +941,7 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const auto ttctx = compiler::TargetTypeContext(etsg, expr->TsType()); ES2PANDA_ASSERT(expr->PropVar()->TsType() != nullptr); const checker::Type *const variableType = expr->PropVar()->TsType(); + ES2PANDA_ASSERT(variableType != nullptr); if (variableType->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { if (expr->Object()->IsSuperExpression()) { etsg->CallExact(expr, variableType->AsETSFunctionType()->FindGetter()->InternalName(), objReg); @@ -959,6 +962,7 @@ void ETSCompiler::Compile(const ir::MemberExpression *expr) const bool ETSCompiler::HandleArrayTypeLengthProperty(const ir::MemberExpression *expr, ETSGen *etsg) const { auto *const objectType = etsg->Checker()->GetApparentType(expr->Object()->TsType()); + ES2PANDA_ASSERT(objectType != nullptr); auto &propName = expr->Property()->AsIdentifier()->Name(); if (objectType->IsETSArrayType() && propName.Is("length")) { auto ottctx = compiler::TargetTypeContext(etsg, objectType); @@ -982,6 +986,7 @@ bool ETSCompiler::HandleStaticProperties(const ir::MemberExpression *expr, ETSGe if (auto const *const varType = variable->TsType(); varType->HasTypeFlag(checker::TypeFlag::GETTER_SETTER)) { checker::Signature *sig = varType->AsETSFunctionType()->FindGetter(); + ES2PANDA_ASSERT(sig != nullptr); etsg->CallExact(expr, sig->InternalName()); etsg->SetAccumulatorType(expr->TsType()); } else { diff --git a/ets2panda/compiler/core/ETSemitter.cpp b/ets2panda/compiler/core/ETSemitter.cpp index baf96ce455..79c1fa5fa6 100644 --- a/ets2panda/compiler/core/ETSemitter.cpp +++ b/ets2panda/compiler/core/ETSemitter.cpp @@ -144,6 +144,7 @@ static pandasm::Function GenScriptFunction(const ir::ScriptFunction *scriptFunc, uint32_t accessFlags = 0; if (!scriptFunc->IsStaticBlock()) { const auto *methodDef = util::Helpers::GetContainingClassMethodDefinition(scriptFunc); + ES2PANDA_ASSERT(methodDef != nullptr); accessFlags |= TranslateModifierFlags(methodDef->Modifiers()); } if (scriptFunc->HasRestParameter()) { @@ -449,6 +450,7 @@ void ETSEmitter::GenInterfaceMethodDefinition(const ir::MethodDefinition *method void ETSEmitter::GenClassField(const ir::ClassProperty *prop, pandasm::Record &classRecord, bool external) { auto field = pandasm::Field(Program()->lang); + ES2PANDA_ASSERT(prop->Id() != nullptr); field.name = prop->Id()->Name().Mutf8(); field.type = PandasmTypeWithRank(prop->TsType()); field.metadata->SetAccessFlags(TranslateModifierFlags(prop->Modifiers())); @@ -685,6 +687,7 @@ static void CreateEnumProp(const ir::ClassProperty *prop, pandasm::Field &field) return; } field.metadata->SetFieldType(field.type); + ES2PANDA_ASSERT(prop->Value()->AsMemberExpression()->PropVar() != nullptr); auto declNode = prop->Value()->AsMemberExpression()->PropVar()->Declaration()->Node(); auto *init = declNode->AsClassProperty()->OriginEnumMember()->Init(); if (init->IsNumberLiteral()) { @@ -702,6 +705,7 @@ static void ProcessEnumExpression(std::vector &l { auto *memberExpr = elem->IsCallExpression() ? elem->AsCallExpression()->Arguments()[0]->AsMemberExpression() : elem->AsMemberExpression(); + ES2PANDA_ASSERT(memberExpr->PropVar() != nullptr); auto *init = memberExpr->PropVar()->Declaration()->Node()->AsClassProperty()->OriginEnumMember()->Init(); if (init->IsNumberLiteral()) { auto enumValue = static_cast(init->AsNumberLiteral()->Number().GetInt()); @@ -816,6 +820,7 @@ void ETSEmitter::GenCustomAnnotationProp(const ir::ClassProperty *prop, std::str { auto field = pandasm::Field(Program()->lang); auto *type = prop->TsType(); + ES2PANDA_ASSERT(prop->Id() != nullptr); field.name = prop->Id()->Name().Mutf8(); field.type = PandasmTypeWithRank(type); field.metadata->SetAccessFlags(TranslateModifierFlags(prop->Modifiers())); @@ -859,6 +864,7 @@ void ETSEmitter::GenCustomAnnotationRecord(const ir::AnnotationDeclaration *anno pandasm::AnnotationElement ETSEmitter::ProcessArrayType(const ir::ClassProperty *prop, std::string &baseName, const ir::Expression *init) { + ES2PANDA_ASSERT(prop->Id() != nullptr); auto propName = prop->Id()->Name().Mutf8(); std::string newBaseName = GenerateMangledName(baseName, propName); auto litArrays = CreateLiteralArray(newBaseName, init); @@ -875,6 +881,7 @@ pandasm::AnnotationElement ETSEmitter::ProcessArrayType(const ir::ClassProperty static pandasm::AnnotationElement ProcessETSEnumType(std::string &baseName, const ir::Expression *init, const checker::Type *type) { + ES2PANDA_ASSERT(init->AsMemberExpression()->PropVar() != nullptr); auto declNode = init->AsMemberExpression()->PropVar()->Declaration()->Node(); auto *initValue = declNode->AsClassProperty()->OriginEnumMember()->Init(); if (type->IsETSIntEnumType()) { @@ -900,6 +907,7 @@ pandasm::AnnotationElement ETSEmitter::GenCustomAnnotationElement(const ir::Clas } if (init->IsLiteral()) { auto typeKind = checker::ETSChecker::TypeKind(type); + ES2PANDA_ASSERT(prop->Id() != nullptr); auto propName = prop->Id()->Name().Mutf8(); return pandasm::AnnotationElement { propName, std::make_unique(CreateScalarValue(init->AsLiteral(), typeKind))}; @@ -1024,6 +1032,7 @@ pandasm::AnnotationData ETSEmitter::GenAnnotationEnclosingMethod(const ir::Metho { GenAnnotationRecord(Signatures::ETS_ANNOTATION_ENCLOSING_METHOD); pandasm::AnnotationData enclosingMethod(Signatures::ETS_ANNOTATION_ENCLOSING_METHOD); + ES2PANDA_ASSERT(methodDef->Function() != nullptr); pandasm::AnnotationElement value( Signatures::ANNOTATION_KEY_VALUE, std::make_unique(pandasm::ScalarValue::Create( @@ -1037,6 +1046,7 @@ pandasm::AnnotationData ETSEmitter::GenAnnotationFunctionalReference(const ir::C GenAnnotationRecord(Signatures::ETS_ANNOTATION_FUNCTIONAL_REFERENCE); pandasm::AnnotationData functionalReference(Signatures::ETS_ANNOTATION_FUNCTIONAL_REFERENCE); bool isStatic = classDef->FunctionalReferenceReferencedMethod()->IsStatic(); + ES2PANDA_ASSERT(const_cast(classDef) != nullptr); pandasm::AnnotationElement value( Signatures::ANNOTATION_KEY_VALUE, std::make_unique( @@ -1113,6 +1123,7 @@ ir::MethodDefinition *ETSEmitter::FindAsyncImpl(ir::ScriptFunction *asyncFunc) auto *checker = static_cast(Context()->GetChecker()); checker::TypeRelation *typeRel = checker->Relation(); checker::SavedTypeRelationFlagsContext savedFlagsCtx(typeRel, checker::TypeRelationFlag::NO_RETURN_TYPE_CHECK); + ES2PANDA_ASSERT(method->Function() != nullptr); method->Function()->Signature()->IsSubtypeOf(typeRel, asyncFunc->Signature()); if (typeRel->IsTrue()) { return method; @@ -1131,6 +1142,7 @@ pandasm::AnnotationData ETSEmitter::GenAnnotationAsync(ir::ScriptFunction *scrip GenAnnotationRecord(Signatures::ETS_COROUTINE_ASYNC); const ir::MethodDefinition *impl = FindAsyncImpl(scriptFunc); ES2PANDA_ASSERT(impl != nullptr); + ES2PANDA_ASSERT(impl->Function() != nullptr); pandasm::AnnotationData ann(Signatures::ETS_COROUTINE_ASYNC); pandasm::AnnotationElement value( Signatures::ANNOTATION_KEY_VALUE, diff --git a/ets2panda/compiler/core/JSCompiler.cpp b/ets2panda/compiler/core/JSCompiler.cpp index b7cb2f00d3..f283dccf56 100644 --- a/ets2panda/compiler/core/JSCompiler.cpp +++ b/ets2panda/compiler/core/JSCompiler.cpp @@ -260,7 +260,7 @@ static void CompileStaticFieldInitializers(compiler::PandaGen *pg, compiler::VRe prop->Value()->Compile(pg); } - if (prop->IsPrivateElement()) { + if (prop->IsPrivateElement() && prop->Id() != nullptr) { pg->ClassPrivateFieldAdd(prop, classReg, classReg, prop->Id()->Name()); continue; } @@ -395,6 +395,7 @@ void JSCompiler::Compile(const ir::ClassDefinition *node) const compiler::LocalRegScope lrs(pg, node->Scope()); compiler::VReg baseReg = CompileHeritageClause(pg, node); + ES2PANDA_ASSERT(node->Ctor() != nullptr); util::StringView ctorId = node->Ctor()->Function()->Scope()->InternalName(); util::BitSet compiled(node->Body().size()); diff --git a/ets2panda/compiler/core/dynamicContext.cpp b/ets2panda/compiler/core/dynamicContext.cpp index 2cb7dab7ba..529caf5327 100644 --- a/ets2panda/compiler/core/dynamicContext.cpp +++ b/ets2panda/compiler/core/dynamicContext.cpp @@ -69,6 +69,7 @@ LexEnvContext::LexEnvContext(LoopEnvScope *envScope, PandaGen *pg, LabelTarget t } catchTable_ = Cg()->CreateCatchTable(); + ES2PANDA_ASSERT(catchTable_ != nullptr); const auto &labelSet = catchTable_->LabelSet(); const auto *node = envScope_->Scope()->Node(); @@ -219,6 +220,8 @@ void ETSTryContext::EmitFinalizer( auto *etsg = static_cast(Cg()); CatchTable *finalizerTable = AddNewCathTable("", trycatchLabelPair); + ES2PANDA_ASSERT(finalizerTable != nullptr); + // First compile of the finaly clause, executed if the statement executed normally tryStmt_->FinallyBlock()->Compile(etsg); diff --git a/ets2panda/compiler/core/moduleContext.cpp b/ets2panda/compiler/core/moduleContext.cpp index 659d61305c..2ebd110a23 100644 --- a/ets2panda/compiler/core/moduleContext.cpp +++ b/ets2panda/compiler/core/moduleContext.cpp @@ -36,6 +36,7 @@ void CompileImports(PandaGen *pg, varbinder::ModuleScope *scope) for (const auto *decl : decls) { varbinder::Variable *v = scope->FindLocal(decl->LocalName(), varbinder::ResolveBindingOptions::BINDINGS); + ES2PANDA_ASSERT(v != nullptr); if (!v->IsModuleVariable()) { ES2PANDA_ASSERT(decl->ImportName() == "*"); diff --git a/ets2panda/compiler/core/pandagen.cpp b/ets2panda/compiler/core/pandagen.cpp index 3438850966..d4602f2bea 100644 --- a/ets2panda/compiler/core/pandagen.cpp +++ b/ets2panda/compiler/core/pandagen.cpp @@ -1786,6 +1786,7 @@ void PandaGen::DirectEval(const ir::AstNode *node, uint32_t parserStatus) const auto *iter = Scope()->EnclosingVariableScope(); while (true) { + ES2PANDA_ASSERT(iter != nullptr); uint32_t scopeBindingsBuf = iter->EvalBindings(); if (scopeBindingsBuf != INVALID_LITERAL_BUFFER_ID) { Sa().Emit(node, util::Helpers::ToStringView(Allocator(), scopeBindingsBuf)); diff --git a/ets2panda/compiler/core/regAllocator.cpp b/ets2panda/compiler/core/regAllocator.cpp index 408daed8c6..9f17711474 100644 --- a/ets2panda/compiler/core/regAllocator.cpp +++ b/ets2panda/compiler/core/regAllocator.cpp @@ -145,6 +145,7 @@ RegAllocator::RegAllocator(CodeGen *const cg, RegSpiller *const spiller) noexcep void RegAllocator::Run(IRNode *const ins, const int32_t spillMax) { ES2PANDA_ASSERT(Spiller().Restored()); + ES2PANDA_ASSERT(ins != nullptr); std::array regs {}; const auto regCnt = ins->Registers(®s); const auto registers = @@ -212,6 +213,7 @@ RangeRegAllocator::RangeRegAllocator(CodeGen *const cg, RegSpiller *const spille void RangeRegAllocator::Run(IRNode *const ins, VReg rangeStart, const std::size_t argCount) { ES2PANDA_ASSERT(Spiller().Restored()); + ES2PANDA_ASSERT(ins != nullptr); const auto rangeEnd = rangeStart + argCount; std::array regs {}; diff --git a/ets2panda/compiler/lowering/ets/ambientLowering.cpp b/ets2panda/compiler/lowering/ets/ambientLowering.cpp index 3a52acabc8..5e88122100 100644 --- a/ets2panda/compiler/lowering/ets/ambientLowering.cpp +++ b/ets2panda/compiler/lowering/ets/ambientLowering.cpp @@ -82,6 +82,7 @@ ir::MethodDefinition *CreateMethodFunctionDefinition(ir::DummyNode *node, public methodDefinition->SetParent(node->Parent()); methodDefinition->AddModifier(ir::ModifierFlags::DECLARE); + ES2PANDA_ASSERT(methodDefinition->AsMethodDefinition()->Function() != nullptr); methodDefinition->AsMethodDefinition()->Function()->AddModifier(ir::ModifierFlags::DECLARE); return methodDefinition->AsMethodDefinition(); } diff --git a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp index 42a8564a0f..3d4f3e5b15 100644 --- a/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/arrayLiteralLowering.cpp @@ -44,6 +44,8 @@ ArenaVector ArrayLiteralLowering::GenerateDefaultCallToConstruc auto *indexSymbol = Gensym(Allocator()); auto *lengthSymbol = Gensym(Allocator()); auto *typeNode = checker_->AllocNode(eleType, Allocator()); + ES2PANDA_ASSERT(typeNode != nullptr); + ss << "let @@I1 : int = @@I2.length.toInt();"; newStmts.emplace_back(lengthSymbol); newStmts.emplace_back(arraySymbol->Clone(Allocator(), nullptr)); @@ -110,6 +112,7 @@ ir::AstNode *ArrayLiteralLowering::TryTransformLiteralArrayToRefArray(ir::ArrayE auto *parent = literalArray->Parent(); auto *loweringResult = parser_->CreateFormattedExpression(ss.str(), newStmts); + ES2PANDA_ASSERT(loweringResult != nullptr); loweringResult->SetRange(literalArray->Range()); loweringResult->SetParent(parent); diff --git a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp index 4d403512f6..1affd68bbf 100644 --- a/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp +++ b/ets2panda/compiler/lowering/ets/asyncMethodLowering.cpp @@ -32,6 +32,7 @@ static void CreateFuncDecl(checker::ETSChecker *checker, ir::MethodDefinition *f auto *varBinder = checker->VarBinder(); // Add the function declarations to the lambda class scope auto ctx = varbinder::LexicalScope::Enter(varBinder, scope); + ES2PANDA_ASSERT(func->Id() != nullptr); varbinder::Variable *var = scope->FindLocal(func->Id()->Name(), varbinder::ResolveBindingOptions::ALL_DECLARATION); if (var == nullptr) { var = std::get<1>( @@ -53,6 +54,7 @@ ir::ETSTypeReference *CreateAsyncImplMethodReturnTypeAnnotation(checker::ETSChec auto *returnTypeAnn = checker->AllocNode( checker->AllocNode(objectId, nullptr, nullptr, checker->Allocator()), checker->Allocator()); + ES2PANDA_ASSERT(returnTypeAnn != nullptr); objectId->SetParent(returnTypeAnn->Part()); returnTypeAnn->Part()->SetParent(returnTypeAnn); @@ -76,6 +78,7 @@ ir::MethodDefinition *CreateAsyncImplMethod(checker::ETSChecker *checker, ir::Me // clear ASYNC flag for implementation modifiers &= ~ir::ModifierFlags::ASYNC; ir::ScriptFunction *asyncFunc = asyncMethod->Function(); + ES2PANDA_ASSERT(asyncFunc != nullptr); ir::ScriptFunctionFlags flags = ir::ScriptFunctionFlags::METHOD; if (asyncFunc->IsProxy()) { @@ -130,6 +133,7 @@ ir::MethodDefinition *CreateAsyncProxy(checker::ETSChecker *checker, ir::MethodD } ir::MethodDefinition *implMethod = CreateAsyncImplMethod(checker, asyncMethod, classDef); + ES2PANDA_ASSERT(implMethod->Function() != nullptr); varbinder::FunctionScope *implFuncScope = implMethod->Function()->Scope(); for (auto *decl : asyncFunc->Scope()->Decls()) { auto res = asyncFunc->Scope()->Bindings().find(decl->Name()); @@ -178,7 +182,7 @@ void ComposeAsyncImplMethod(checker::ETSChecker *checker, ir::MethodDefinition * void HandleMethod(checker::ETSChecker *checker, ir::MethodDefinition *node) { ES2PANDA_ASSERT(!node->TsType()->IsTypeError()); - if (util::Helpers::IsAsyncMethod(node) && !node->Function()->IsExternal()) { + if (util::Helpers::IsAsyncMethod(node) && node->Function() != nullptr && !node->Function()->IsExternal()) { ComposeAsyncImplMethod(checker, node); } diff --git a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp index ce8e088aa6..0277b45394 100644 --- a/ets2panda/compiler/lowering/ets/boxingForLocals.cpp +++ b/ets2panda/compiler/lowering/ets/boxingForLocals.cpp @@ -14,6 +14,7 @@ */ #include "boxingForLocals.h" +#include #include "compiler/lowering/util.h" #include "checker/ETSchecker.h" @@ -132,6 +133,7 @@ static void HandleFunctionParam(public_lib::Context *ctx, ir::ETSParameterExpres auto *scope = body->Scope(); auto *initId = allocator->New(id->Name(), allocator); + ES2PANDA_ASSERT(initId != nullptr); initId->SetVariable(id->Variable()); initId->SetTsType(oldType); initId->SetRange(id->Range()); @@ -204,6 +206,8 @@ static ir::AstNode *HandleVariableDeclarator(public_lib::Context *ctx, ir::Varia allocator, allocator->New(boxedType, allocator), std::move(initArgs)); auto *newDeclarator = util::NodeAllocator::ForceSetParent( allocator, declarator->Flag(), allocator->New(id->Name(), allocator), newInit); + ES2PANDA_ASSERT(newDeclarator != nullptr); + newDeclarator->SetParent(declarator->Parent()); newInit->GetTypeRef()->SetRange(declarator->Range()); diff --git a/ets2panda/evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp b/ets2panda/evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp index 56a8350b50..a84486f5f5 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/debugInfoDeserializer.cpp @@ -140,11 +140,12 @@ varbinder::Variable *DebugInfoDeserializer::CreateIrGlobalVariable(parser::Progr auto *checkHelper = debugInfoPlugin_.GetIrCheckHelper(); const auto *pf = debugInfoStorage->GetPandaFile(pathToSource.Utf8()); - ES2PANDA_ASSERT(pf); + ES2PANDA_ASSERT(pf != nullptr); varbinder::Variable *var = nullptr; auto *cda = debugInfoStorage->GetGlobalClassAccessor(pathToSource.Utf8()); + ES2PANDA_ASSERT(cda != nullptr); cda->EnumerateFields([program, varDeclName, pf, &var, checkHelper](panda_file::FieldDataAccessor &fda) { // All ETSGLOBAL fields must be static. ES2PANDA_ASSERT(fda.IsStatic()); @@ -183,6 +184,7 @@ varbinder::Variable *DebugInfoDeserializer::CreateIrGlobalMethods(ArenaVectorGetGlobalClassAccessor(pathToSource.Utf8()); + ES2PANDA_ASSERT(cda != nullptr); cda->EnumerateMethods([this, &var, &createdMethods, program, methodDeclName, &cda](panda_file::MethodDataAccessor &mda) { if (!methodDeclName.Is(mda.GetFullName())) { diff --git a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp index 581b830fde..a2326cba1b 100644 --- a/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp +++ b/ets2panda/evaluate/debugInfoDeserialization/methodBuilder.cpp @@ -172,6 +172,7 @@ ir::AstNode *MethodBuilder::CreateIrConstructor(ir::Identifier *id, ir::BlockSta if constexpr (IS_STATIC) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *staticBlock = checker_->AllocNode(funcExpr, allocator); + ES2PANDA_ASSERT(staticBlock != nullptr); staticBlock->AddModifier(ir::ModifierFlags::STATIC); return staticBlock; } @@ -185,6 +186,7 @@ ir::MethodDefinition *MethodBuilder::CreateIrMethod(ir::Identifier *id, ir::Bloc { auto *allocator = checker_->Allocator(); auto *funcExpr = CreateFunctionExpression(id, body, ir::ScriptFunctionFlags::METHOD); + ES2PANDA_ASSERT(funcExpr != nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *method = checker_->AllocNode(ir::MethodDefinitionKind::METHOD, funcExpr->Function()->Id()->Clone(allocator, nullptr), @@ -202,6 +204,7 @@ ir::FunctionExpression *MethodBuilder::CreateFunctionExpression(ir::Identifier * checker_->Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(funcSignature), scriptFuncFlags, modifierFlags_}); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); func->SetReturnTypeAnnotation(returnType_); diff --git a/ets2panda/evaluate/helpers.cpp b/ets2panda/evaluate/helpers.cpp index 210e57abe7..e41daa9022 100644 --- a/ets2panda/evaluate/helpers.cpp +++ b/ets2panda/evaluate/helpers.cpp @@ -243,7 +243,7 @@ std::optional ToTypeName(std::string_view typeSignature, checker::G pandasm::Type type = pandasm::Type::FromDescriptor(typeSignature); auto *checkerType = PrimitiveToCheckerType(type.GetId(), globalTypes); - ES2PANDA_ASSERT(checkerType); + ES2PANDA_ASSERT(checkerType != nullptr); return checkerType->ToString(); } diff --git a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp index 16b6396f9f..501927fd03 100644 --- a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp +++ b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp @@ -33,6 +33,7 @@ ir::VariableDeclaration *CreateVariableDeclaration(checker::ETSChecker *checker, ir::Expression *init) { auto *declarator = checker->AllocNode(ir::VariableDeclaratorFlag::CONST, ident, init); + ES2PANDA_ASSERT(declarator != nullptr); ArenaVector declarators(1, declarator, checker->Allocator()->Adapter()); auto *declaration = checker->AllocNode( @@ -404,6 +405,7 @@ parser::Program *ScopedDebugInfoPlugin::CreateEmptyProgram(std::string_view sour // Checker doesn't yet have `VarBinder`, must retrieve it from `globalProgram_`. parser::Program *program = allocator->New(allocator, GetETSBinder()); + ES2PANDA_ASSERT(program != nullptr); program->SetSource({sourceFilePath, "", globalProgram_->SourceFileFolder().Utf8(), true, false}); program->SetPackageInfo(moduleName, util::ModuleKind::MODULE); auto *emptyIdent = allocator->New("", allocator); diff --git a/ets2panda/ir/base/catchClause.cpp b/ets2panda/ir/base/catchClause.cpp index 53b37af715..c4c120f155 100644 --- a/ets2panda/ir/base/catchClause.cpp +++ b/ets2panda/ir/base/catchClause.cpp @@ -96,13 +96,20 @@ checker::VerifiedType CatchClause::Check(checker::ETSChecker *checker) CatchClause::CatchClause(CatchClause const &other, ArenaAllocator *allocator) : TypedStatement(other) { - param_ = other.param_ == nullptr ? nullptr : other.param_->Clone(allocator, this)->AsExpression(); - body_ = other.body_ == nullptr ? nullptr : other.body_->Clone(allocator, this)->AsBlockStatement(); + param_ = nullptr; + body_ = nullptr; + if (other.param_ != nullptr && other.param_->Clone(allocator, this) != nullptr) { + param_ = other.param_->Clone(allocator, this)->AsExpression(); + } + if (other.body_ != nullptr && other.body_->Clone(allocator, this) != nullptr) { + body_ = other.body_->Clone(allocator, this)->AsBlockStatement(); + } } CatchClause *CatchClause::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/base/decorator.cpp b/ets2panda/ir/base/decorator.cpp index 08bb4ffc5c..573093d668 100644 --- a/ets2panda/ir/base/decorator.cpp +++ b/ets2panda/ir/base/decorator.cpp @@ -68,6 +68,7 @@ Decorator *Decorator::Clone(ArenaAllocator *const allocator, AstNode *const pare { auto *const expr = expr_ != nullptr ? expr_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(expr); + ES2PANDA_ASSERT(clone != nullptr); if (expr != nullptr) { expr->SetParent(clone); diff --git a/ets2panda/ir/base/metaProperty.cpp b/ets2panda/ir/base/metaProperty.cpp index fcb85de132..38bed829d8 100644 --- a/ets2panda/ir/base/metaProperty.cpp +++ b/ets2panda/ir/base/metaProperty.cpp @@ -76,6 +76,7 @@ checker::VerifiedType MetaProperty::Check(checker::ETSChecker *checker) MetaProperty *MetaProperty::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(kind_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/base/methodDefinition.cpp b/ets2panda/ir/base/methodDefinition.cpp index c226b741b3..d2ac48bf3d 100644 --- a/ets2panda/ir/base/methodDefinition.cpp +++ b/ets2panda/ir/base/methodDefinition.cpp @@ -299,6 +299,7 @@ bool MethodDefinition::FilterForDeclGen(ir::SrcDumper *dumper) const return true; } + ES2PANDA_ASSERT(Id() != nullptr); auto name = Id()->Name().Mutf8(); if (name.find("$asyncimpl") != std::string::npos || name == compiler::Signatures::INITIALIZER_BLOCK_INIT || name == compiler::Signatures::INIT_METHOD) { @@ -326,7 +327,7 @@ void MethodDefinition::Dump(ir::SrcDumper *dumper) const return; } - if (compiler::HasGlobalClassParent(this) && Id()->Name().Is(compiler::Signatures::INIT_METHOD)) { + if (compiler::HasGlobalClassParent(this) && Id() != nullptr && Id()->Name().Is(compiler::Signatures::INIT_METHOD)) { Function()->Body()->Dump(dumper); return; } diff --git a/ets2panda/ir/base/methodDefinition.h b/ets2panda/ir/base/methodDefinition.h index af54efb580..6ae3271cf5 100644 --- a/ets2panda/ir/base/methodDefinition.h +++ b/ets2panda/ir/base/methodDefinition.h @@ -193,6 +193,7 @@ public: ES2PANDA_ASSERT(overload != nullptr); auto newNode = this->GetOrCreateHistoryNode()->AsMethodDefinition(); newNode->overloads_.emplace_back(overload); + ES2PANDA_ASSERT(overload->Function() != nullptr); overload->Function()->AddFlag((ir::ScriptFunctionFlags::OVERLOAD)); overload->SetBaseOverloadMethod(this); } diff --git a/ets2panda/ir/base/property.cpp b/ets2panda/ir/base/property.cpp index 24deab39d0..531954ca21 100644 --- a/ets2panda/ir/base/property.cpp +++ b/ets2panda/ir/base/property.cpp @@ -33,6 +33,7 @@ Property *Property::Clone(ArenaAllocator *const allocator, AstNode *const parent auto *const key = key_ != nullptr ? key_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const value = value_ != nullptr ? value_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(Tag {}, *this, key, value); + ES2PANDA_ASSERT(clone != nullptr); if (key != nullptr) { key->SetParent(clone); diff --git a/ets2panda/ir/base/scriptFunction.cpp b/ets2panda/ir/base/scriptFunction.cpp index 733d69eb83..ce9683e82c 100644 --- a/ets2panda/ir/base/scriptFunction.cpp +++ b/ets2panda/ir/base/scriptFunction.cpp @@ -200,6 +200,7 @@ ScriptFunction *ScriptFunction::Clone(ArenaAllocator *allocator, AstNode *parent : nullptr, HasReceiver()}, Flags(), Modifiers(), Language()}); + ES2PANDA_ASSERT(res != nullptr); res->SetParent(parent); res->SetAnnotations(std::move(annotationUsages)); return res; diff --git a/ets2panda/ir/base/spreadElement.cpp b/ets2panda/ir/base/spreadElement.cpp index a841793031..39bac966aa 100644 --- a/ets2panda/ir/base/spreadElement.cpp +++ b/ets2panda/ir/base/spreadElement.cpp @@ -36,6 +36,7 @@ SpreadElement::SpreadElement([[maybe_unused]] Tag const tag, SpreadElement const SpreadElement *SpreadElement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/base/templateElement.cpp b/ets2panda/ir/base/templateElement.cpp index 6ab35fff9e..4ba3be396a 100644 --- a/ets2panda/ir/base/templateElement.cpp +++ b/ets2panda/ir/base/templateElement.cpp @@ -63,6 +63,7 @@ checker::VerifiedType TemplateElement::Check(checker::ETSChecker *checker) TemplateElement *TemplateElement::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(raw_, cooked_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/base/tsIndexSignature.cpp b/ets2panda/ir/base/tsIndexSignature.cpp index ae7cd74478..22d8a78b56 100644 --- a/ets2panda/ir/base/tsIndexSignature.cpp +++ b/ets2panda/ir/base/tsIndexSignature.cpp @@ -83,6 +83,7 @@ TSIndexSignature *TSIndexSignature::Clone(ArenaAllocator *const allocator, AstNo auto *const param = param_ != nullptr ? param_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const typeAnnotation = typeAnnotation_->Clone(allocator, nullptr); auto *const clone = allocator->New(param, typeAnnotation, readonly_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/base/tsPropertySignature.cpp b/ets2panda/ir/base/tsPropertySignature.cpp index 7c993c2ad7..d1a2bb2ee1 100644 --- a/ets2panda/ir/base/tsPropertySignature.cpp +++ b/ets2panda/ir/base/tsPropertySignature.cpp @@ -85,6 +85,7 @@ TSPropertySignature *TSPropertySignature::Clone(ArenaAllocator *const allocator, auto *const typeAnnotation = TypeAnnotation()->Clone(allocator, nullptr); auto *const clone = allocator->New(key, typeAnnotation, computed_, optional_, readonly_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/expressions/callExpression.cpp b/ets2panda/ir/expressions/callExpression.cpp index 4333ae3e9b..c0619e941d 100644 --- a/ets2panda/ir/expressions/callExpression.cpp +++ b/ets2panda/ir/expressions/callExpression.cpp @@ -147,6 +147,7 @@ CallExpression::CallExpression(CallExpression const &other, ArenaAllocator *cons CallExpression *CallExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/chainExpression.cpp b/ets2panda/ir/expressions/chainExpression.cpp index d805249fd3..8407013cb3 100644 --- a/ets2panda/ir/expressions/chainExpression.cpp +++ b/ets2panda/ir/expressions/chainExpression.cpp @@ -82,6 +82,7 @@ ChainExpression *ChainExpression::Clone(ArenaAllocator *const allocator, AstNode { auto *const expression = expression_ != nullptr ? expression_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(expression); + ES2PANDA_ASSERT(clone != nullptr); if (expression != nullptr) { expression->SetParent(clone); diff --git a/ets2panda/ir/expressions/classExpression.cpp b/ets2panda/ir/expressions/classExpression.cpp index d5d8d83cfb..36a0f7fa2e 100644 --- a/ets2panda/ir/expressions/classExpression.cpp +++ b/ets2panda/ir/expressions/classExpression.cpp @@ -67,6 +67,7 @@ ClassExpression *ClassExpression::Clone(ArenaAllocator *const allocator, AstNode { auto *const def = def_ != nullptr ? def_->Clone(allocator, nullptr)->AsClassDefinition() : nullptr; auto *const clone = allocator->New(def); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/expressions/functionExpression.cpp b/ets2panda/ir/expressions/functionExpression.cpp index 8e39aaff4b..b5096815fc 100644 --- a/ets2panda/ir/expressions/functionExpression.cpp +++ b/ets2panda/ir/expressions/functionExpression.cpp @@ -65,8 +65,10 @@ checker::VerifiedType FunctionExpression::Check([[maybe_unused]] checker::ETSChe FunctionExpression *FunctionExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { + ES2PANDA_ASSERT(func_->Clone(allocator, nullptr) != nullptr); auto *const func = func_->Clone(allocator, nullptr)->AsScriptFunction(); auto *const clone = allocator->New(func); + ES2PANDA_ASSERT(clone != nullptr); func->SetParent(clone); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 7689fcca37..57419e8539 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -66,6 +66,7 @@ void Identifier::SetName(const util::StringView &newName) noexcept Identifier *Identifier::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); clone->SetTsType(TsType()); if (parent != nullptr) { @@ -86,6 +87,7 @@ void Identifier::SetValueDecorators(Decorator *source, size_t index) Identifier *Identifier::CloneReference(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = Clone(allocator, parent); + ES2PANDA_ASSERT(clone != nullptr); if (clone->IsReference(ScriptExtension::ETS)) { clone->SetTsTypeAnnotation(nullptr); } diff --git a/ets2panda/ir/expressions/importExpression.cpp b/ets2panda/ir/expressions/importExpression.cpp index 9a0c7d40fe..fc1c140d4d 100644 --- a/ets2panda/ir/expressions/importExpression.cpp +++ b/ets2panda/ir/expressions/importExpression.cpp @@ -66,6 +66,7 @@ ImportExpression *ImportExpression::Clone(ArenaAllocator *const allocator, AstNo { auto *const source = source_ != nullptr ? source_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(source); + ES2PANDA_ASSERT(clone != nullptr); if (source != nullptr) { source->SetParent(clone); diff --git a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp index 0f26558966..95cc4f3eaa 100644 --- a/ets2panda/ir/expressions/literals/bigIntLiteral.cpp +++ b/ets2panda/ir/expressions/literals/bigIntLiteral.cpp @@ -61,6 +61,7 @@ checker::VerifiedType BigIntLiteral::Check([[maybe_unused]] checker::ETSChecker BigIntLiteral *BigIntLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(src_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/booleanLiteral.cpp b/ets2panda/ir/expressions/literals/booleanLiteral.cpp index 70978bdfeb..01025493fb 100644 --- a/ets2panda/ir/expressions/literals/booleanLiteral.cpp +++ b/ets2panda/ir/expressions/literals/booleanLiteral.cpp @@ -61,6 +61,7 @@ checker::VerifiedType BooleanLiteral::Check([[maybe_unused]] checker::ETSChecker BooleanLiteral *BooleanLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(boolean_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/charLiteral.cpp b/ets2panda/ir/expressions/literals/charLiteral.cpp index de15b808ba..3dcd401f22 100644 --- a/ets2panda/ir/expressions/literals/charLiteral.cpp +++ b/ets2panda/ir/expressions/literals/charLiteral.cpp @@ -61,6 +61,7 @@ checker::VerifiedType CharLiteral::Check([[maybe_unused]] checker::ETSChecker *c CharLiteral *CharLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(char_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/nullLiteral.cpp b/ets2panda/ir/expressions/literals/nullLiteral.cpp index 0155309c84..f88e2e8532 100644 --- a/ets2panda/ir/expressions/literals/nullLiteral.cpp +++ b/ets2panda/ir/expressions/literals/nullLiteral.cpp @@ -60,6 +60,7 @@ checker::VerifiedType NullLiteral::Check(checker::ETSChecker *checker) NullLiteral *NullLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/numberLiteral.cpp b/ets2panda/ir/expressions/literals/numberLiteral.cpp index 2d21d34317..d3cf60f026 100644 --- a/ets2panda/ir/expressions/literals/numberLiteral.cpp +++ b/ets2panda/ir/expressions/literals/numberLiteral.cpp @@ -99,6 +99,7 @@ checker::VerifiedType NumberLiteral::Check(checker::ETSChecker *checker) NumberLiteral *NumberLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(number_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } @@ -264,7 +265,7 @@ static Span FpToStringDecimalRadixMainCase(FpType number, bool negative, S // 8. If −6 < n ≤ 0, return the String consisting of the code unit 0x0030 (DIGIT ZERO), followed by the code // unit 0x002E (FULL STOP), followed by −n occurrences of the code unit 0x0030 (DIGIT ZERO), followed by the // code units of the k digits of the decimal representation of s. - auto length = -n + 2U; + size_t length = -n + 2U; auto fracStart = bufferStart + length; if (memmove_s(fracStart, buffer.end() - fracStart, bufferStart, k) != EOK) { ES2PANDA_UNREACHABLE(); @@ -323,7 +324,7 @@ static char *SmallFpToString(FpType number, bool negative, char *buffer) power *= TEN; } for (int k = digits - 1; k >= 0; k--) { - auto digit = s % TEN; + auto digit = std::abs(s) % TEN; s /= TEN; *(buffer + k) = '0' + digit; } diff --git a/ets2panda/ir/expressions/literals/regExpLiteral.cpp b/ets2panda/ir/expressions/literals/regExpLiteral.cpp index 88bbde3447..71b31dc0c9 100644 --- a/ets2panda/ir/expressions/literals/regExpLiteral.cpp +++ b/ets2panda/ir/expressions/literals/regExpLiteral.cpp @@ -61,6 +61,7 @@ checker::VerifiedType RegExpLiteral::Check(checker::ETSChecker *checker) RegExpLiteral *RegExpLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(pattern_, flags_, flagsStr_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/stringLiteral.cpp b/ets2panda/ir/expressions/literals/stringLiteral.cpp index 804404ffdf..c0345f6b61 100644 --- a/ets2panda/ir/expressions/literals/stringLiteral.cpp +++ b/ets2panda/ir/expressions/literals/stringLiteral.cpp @@ -60,6 +60,7 @@ checker::VerifiedType StringLiteral::Check(checker::ETSChecker *checker) StringLiteral *StringLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(str_); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp index c70b049e0c..d30067ede8 100644 --- a/ets2panda/ir/expressions/literals/undefinedLiteral.cpp +++ b/ets2panda/ir/expressions/literals/undefinedLiteral.cpp @@ -64,6 +64,7 @@ checker::VerifiedType UndefinedLiteral::Check(checker::ETSChecker *checker) UndefinedLiteral *UndefinedLiteral::Clone(ArenaAllocator *allocator, AstNode *parent) { auto *const clone = allocator->New(); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index ae65ae697c..2d6ceba699 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -230,6 +230,7 @@ checker::Type *MemberExpression::TraverseUnionMember(checker::ETSChecker *checke for (auto *const type : unionType->ConstituentTypes()) { auto *const apparent = checker->GetApparentType(type); + ES2PANDA_ASSERT(apparent != nullptr); if (apparent->IsETSObjectType()) { SetObjectType(apparent->AsETSObjectType()); addPropType(ResolveObjectMember(checker).first); @@ -285,6 +286,7 @@ static checker::Type *AdjustRecordReturnType(checker::Type *type, checker::Type checker::Type *MemberExpression::AdjustType(checker::ETSChecker *checker, checker::Type *type) { auto *const objType = checker->GetApparentType(Object()->TsType()); + ES2PANDA_ASSERT(objType != nullptr); if (type != nullptr && objType->IsETSObjectType() && objType->ToAssemblerName().str() == compiler::Signatures::BUILTIN_RECORD) { type = AdjustRecordReturnType(type, objType); @@ -540,6 +542,7 @@ checker::VerifiedType MemberExpression::Check(checker::ETSChecker *checker) MemberExpression *MemberExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/newExpression.cpp b/ets2panda/ir/expressions/newExpression.cpp index 0138a4216c..121a9871a1 100644 --- a/ets2panda/ir/expressions/newExpression.cpp +++ b/ets2panda/ir/expressions/newExpression.cpp @@ -36,6 +36,7 @@ NewExpression::NewExpression([[maybe_unused]] Tag const tag, NewExpression const NewExpression *NewExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/objectExpression.cpp b/ets2panda/ir/expressions/objectExpression.cpp index 062a325899..13fff0d89b 100644 --- a/ets2panda/ir/expressions/objectExpression.cpp +++ b/ets2panda/ir/expressions/objectExpression.cpp @@ -43,6 +43,7 @@ ObjectExpression::ObjectExpression([[maybe_unused]] Tag const tag, ObjectExpress ObjectExpression *ObjectExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } @@ -336,6 +337,7 @@ checker::Type *ObjectExpression::CheckPattern(checker::TSChecker *checker) varbinder::LocalVariable *patternVar = varbinder::Scope::CreateVar( checker->Allocator(), prop->Key()->AsIdentifier()->Name(), varbinder::VariableFlags::PROPERTY, *it); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(patternParamType); if (isOptional) { diff --git a/ets2panda/ir/expressions/omittedExpression.cpp b/ets2panda/ir/expressions/omittedExpression.cpp index 17e99c3377..a804144ab3 100644 --- a/ets2panda/ir/expressions/omittedExpression.cpp +++ b/ets2panda/ir/expressions/omittedExpression.cpp @@ -60,6 +60,7 @@ checker::VerifiedType OmittedExpression::Check(checker::ETSChecker *checker) OmittedExpression *OmittedExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/sequenceExpression.cpp b/ets2panda/ir/expressions/sequenceExpression.cpp index cbe9d5dbbb..f84e542b58 100644 --- a/ets2panda/ir/expressions/sequenceExpression.cpp +++ b/ets2panda/ir/expressions/sequenceExpression.cpp @@ -33,6 +33,7 @@ SequenceExpression::SequenceExpression([[maybe_unused]] Tag const tag, SequenceE SequenceExpression *SequenceExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/superExpression.cpp b/ets2panda/ir/expressions/superExpression.cpp index 2bfb758bfa..027182de8a 100644 --- a/ets2panda/ir/expressions/superExpression.cpp +++ b/ets2panda/ir/expressions/superExpression.cpp @@ -61,6 +61,7 @@ checker::VerifiedType SuperExpression::Check([[maybe_unused]] checker::ETSChecke SuperExpression *SuperExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/taggedTemplateExpression.cpp b/ets2panda/ir/expressions/taggedTemplateExpression.cpp index 54eb9a71c8..069005b553 100644 --- a/ets2panda/ir/expressions/taggedTemplateExpression.cpp +++ b/ets2panda/ir/expressions/taggedTemplateExpression.cpp @@ -89,6 +89,7 @@ TaggedTemplateExpression *TaggedTemplateExpression::Clone(ArenaAllocator *const auto *const quasi = quasi_ != nullptr ? quasi_->Clone(allocator, nullptr) : nullptr; auto *const typeParams = typeParams_ != nullptr ? typeParams_->Clone(allocator, nullptr) : nullptr; auto *const clone = allocator->New(tag, quasi, typeParams); + ES2PANDA_ASSERT(clone != nullptr); if (tag != nullptr) { tag->SetParent(clone); diff --git a/ets2panda/ir/expressions/templateLiteral.cpp b/ets2panda/ir/expressions/templateLiteral.cpp index e7c10eda77..4275fe126a 100644 --- a/ets2panda/ir/expressions/templateLiteral.cpp +++ b/ets2panda/ir/expressions/templateLiteral.cpp @@ -41,6 +41,7 @@ TemplateLiteral::TemplateLiteral([[maybe_unused]] Tag const tag, TemplateLiteral TemplateLiteral *TemplateLiteral::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/thisExpression.cpp b/ets2panda/ir/expressions/thisExpression.cpp index 3323964b98..269fb8a222 100644 --- a/ets2panda/ir/expressions/thisExpression.cpp +++ b/ets2panda/ir/expressions/thisExpression.cpp @@ -61,6 +61,7 @@ checker::VerifiedType ThisExpression::Check(checker::ETSChecker *checker) ThisExpression *ThisExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/expressions/unaryExpression.cpp b/ets2panda/ir/expressions/unaryExpression.cpp index 8cdaa4bdf7..1208f24c21 100644 --- a/ets2panda/ir/expressions/unaryExpression.cpp +++ b/ets2panda/ir/expressions/unaryExpression.cpp @@ -75,6 +75,7 @@ UnaryExpression *UnaryExpression::Clone(ArenaAllocator *const allocator, AstNode { auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(argument, operator_); + ES2PANDA_ASSERT(clone != nullptr); if (argument != nullptr) { argument->SetParent(clone); diff --git a/ets2panda/ir/expressions/updateExpression.cpp b/ets2panda/ir/expressions/updateExpression.cpp index f594e7fc09..4d8f148bf2 100644 --- a/ets2panda/ir/expressions/updateExpression.cpp +++ b/ets2panda/ir/expressions/updateExpression.cpp @@ -77,6 +77,7 @@ UpdateExpression *UpdateExpression::Clone(ArenaAllocator *const allocator, AstNo { auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(argument, operator_, prefix_); + ES2PANDA_ASSERT(clone != nullptr); if (argument != nullptr) { argument->SetParent(clone); diff --git a/ets2panda/ir/expressions/yieldExpression.cpp b/ets2panda/ir/expressions/yieldExpression.cpp index a64f33df86..23e17be10d 100644 --- a/ets2panda/ir/expressions/yieldExpression.cpp +++ b/ets2panda/ir/expressions/yieldExpression.cpp @@ -72,6 +72,7 @@ YieldExpression *YieldExpression::Clone(ArenaAllocator *const allocator, AstNode { auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(argument, delegate_); + ES2PANDA_ASSERT(clone != nullptr); if (argument != nullptr) { argument->SetParent(clone); diff --git a/ets2panda/ir/ts/tsArrayType.cpp b/ets2panda/ir/ts/tsArrayType.cpp index fe5c8a3049..b5f988027e 100644 --- a/ets2panda/ir/ts/tsArrayType.cpp +++ b/ets2panda/ir/ts/tsArrayType.cpp @@ -101,6 +101,7 @@ TSArrayType *TSArrayType::Clone(ArenaAllocator *const allocator, AstNode *const { auto *const elementTypeClone = elementType_ != nullptr ? elementType_->Clone(allocator, nullptr) : nullptr; auto *const clone = allocator->New(elementTypeClone, allocator); + ES2PANDA_ASSERT(clone != nullptr); clone->AddModifier(flags_); diff --git a/ets2panda/ir/ts/tsAsExpression.cpp b/ets2panda/ir/ts/tsAsExpression.cpp index 8452359ba2..90f1c4efca 100644 --- a/ets2panda/ir/ts/tsAsExpression.cpp +++ b/ets2panda/ir/ts/tsAsExpression.cpp @@ -99,6 +99,7 @@ TSAsExpression *TSAsExpression::Clone(ArenaAllocator *const allocator, AstNode * } auto *const clone = allocator->New(expression, typeAnnotation, isConst_); + ES2PANDA_ASSERT(clone != nullptr); if (expression != nullptr) { expression->SetParent(clone); diff --git a/ets2panda/ir/ts/tsQualifiedName.cpp b/ets2panda/ir/ts/tsQualifiedName.cpp index d71f7db781..f47595f293 100644 --- a/ets2panda/ir/ts/tsQualifiedName.cpp +++ b/ets2panda/ir/ts/tsQualifiedName.cpp @@ -134,6 +134,7 @@ const ir::TSQualifiedName *TSQualifiedName::ResolveLeftMostQualifiedName() const TSQualifiedName *TSQualifiedName::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ts/tsThisType.cpp b/ets2panda/ir/ts/tsThisType.cpp index 9af97be93c..03bcb6e6a2 100644 --- a/ets2panda/ir/ts/tsThisType.cpp +++ b/ets2panda/ir/ts/tsThisType.cpp @@ -84,6 +84,7 @@ TSThisType *TSThisType::Clone(ArenaAllocator *const allocator, AstNode *const pa if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone) != nullptr); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/ts/tsTupleType.cpp b/ets2panda/ir/ts/tsTupleType.cpp index a76a006e52..25f14ade82 100644 --- a/ets2panda/ir/ts/tsTupleType.cpp +++ b/ets2panda/ir/ts/tsTupleType.cpp @@ -87,6 +87,12 @@ checker::Type *GetNumberIndexType(ArenaVector numberIndexTypes, return numberIndexType; } +static void SetMemberVarType(checker::Type *memberType, varbinder::LocalVariable *memberVar) +{ + memberType->SetVariable(memberVar); + memberVar->SetTsType(memberType); +} + checker::Type *TSTupleType::GetType(checker::TSChecker *checker) { if (TsType() != nullptr) { @@ -94,6 +100,7 @@ checker::Type *TSTupleType::GetType(checker::TSChecker *checker) } checker::ObjectDescriptor *desc = checker->Allocator()->New(checker->Allocator()); + ES2PANDA_ASSERT(desc != nullptr); checker::NamedTupleMemberPool namedMembers(checker->Allocator()->Adapter()); ArenaVector elementFlags(checker->Allocator()->Adapter()); checker::ElementFlags combinedFlags = checker::ElementFlags::NO_OPTS; @@ -119,14 +126,12 @@ checker::Type *TSTupleType::GetType(checker::TSChecker *checker) minLength++; } - memberType->SetVariable(memberVar); - memberVar->SetTsType(memberType); + SetMemberVarType(memberType, memberVar); numberIndexTypes.push_back(memberType); namedMembers.insert({memberVar, namedMember->Label()->AsIdentifier()->Name()}); } else { checker::Type *memberType = it->GetType(checker); - memberType->SetVariable(memberVar); - memberVar->SetTsType(memberType); + SetMemberVarType(memberType, memberVar); memberFlag = checker::ElementFlags::REQUIRED; numberIndexTypes.push_back(memberType); minLength++; diff --git a/ets2panda/ir/ts/tsTypeLiteral.cpp b/ets2panda/ir/ts/tsTypeLiteral.cpp index 9ebb23b66d..7509640fc8 100644 --- a/ets2panda/ir/ts/tsTypeLiteral.cpp +++ b/ets2panda/ir/ts/tsTypeLiteral.cpp @@ -85,6 +85,7 @@ checker::Type *TSTypeLiteral::GetType(checker::TSChecker *checker) checker::ObjectDescriptor *desc = checker->Allocator()->New(checker->Allocator()); checker::Type *type = checker->Allocator()->New(desc); + ES2PANDA_ASSERT(type != nullptr); type->SetVariable(Variable()); SetTsType(type); diff --git a/ets2panda/ir/ts/tsTypeParameterDeclaration.h b/ets2panda/ir/ts/tsTypeParameterDeclaration.h index 282d0a2f2e..31a3b786fb 100644 --- a/ets2panda/ir/ts/tsTypeParameterDeclaration.h +++ b/ets2panda/ir/ts/tsTypeParameterDeclaration.h @@ -69,6 +69,7 @@ public: void AddParam(TSTypeParameter *param) { + ES2PANDA_ASSERT(param != nullptr); if (RequiredParams() == Params().size() && param->DefaultType() == nullptr) { SetRequiredParams(RequiredParams() + 1); } diff --git a/ets2panda/ir/typeNode.cpp b/ets2panda/ir/typeNode.cpp index 233b4ff768..f45f76c13c 100644 --- a/ets2panda/ir/typeNode.cpp +++ b/ets2panda/ir/typeNode.cpp @@ -22,6 +22,7 @@ TypeNode *TypeNode::Clone(ArenaAllocator *const allocator, AstNode *const parent { if (auto *const type = TsType(); type != nullptr) { auto *const clone = allocator->New(type, allocator); + ES2PANDA_ASSERT(clone != nullptr); if (parent != nullptr) { clone->SetParent(parent); } -- Gitee From 72a22759cf47967ee6353938d826fd155c18a4d8 Mon Sep 17 00:00:00 2001 From: daizihan Date: Fri, 4 Jul 2025 14:59:26 +0800 Subject: [PATCH 031/107] Fix fuzz crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK0DL?from=project-issue Signed-off-by: daizihan --- ets2panda/checker/ets/helpers.cpp | 3 ++- ets2panda/parser/TypedParser.cpp | 3 --- .../test/ast/compiler/ets/fuzzingtest4.ets | 22 ++++++++++++++++++ .../test/ast/compiler/ets/fuzzingtest5.ets | 23 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/fuzzingtest4.ets create mode 100644 ets2panda/test/ast/compiler/ets/fuzzingtest5.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index f7a520764e..cc34bb7a4f 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -43,7 +43,8 @@ std::pair ETSChecker::FindVariable return {nullptr, nullptr}; } const auto searchFlags = PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE | - PropertySearchFlags::SEARCH_IN_INTERFACES; + PropertySearchFlags::SEARCH_IN_INTERFACES | + PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; auto *resolved = classType->GetProperty(name, searchFlags); while (classType->EnclosingType() != nullptr && resolved == nullptr) { classType = classType->EnclosingType(); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index ec8975b8d6..7c59b837f1 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -1219,9 +1219,6 @@ ir::Expression *TypedParser::ParseQualifiedName(ExpressionParseFlags flags) Lexer()->NextToken(); break; default: - if ((flags & ExpressionParseFlags::POTENTIAL_NEW_ARRAY) != 0) { - return expr; - } LogError(diagnostic::ID_EXPECTED); return AllocBrokenExpression(Lexer()->GetToken().Loc()); } diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets new file mode 100644 index 0000000000..93c9fbf39d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest4.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +function foo() { + new CC. +} + +/* @@? 17:9 Error TypeError: Cannot find type 'CC'. */ +/* @@? 18:1 Error SyntaxError: Identifier expected. */ +/* @@? 18:1 Error TypeError: Invalid type reference. */ diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets new file mode 100644 index 0000000000..34e6e9c60d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest5.ets @@ -0,0 +1,23 @@ +/* + * 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 A { + f() { + f = 300 + } +} + +/* @@? 18:9 Error TypeError: Property 'f' must be accessed through 'this' */ +/* @@? 18:13 Error TypeError: Type 'Int' cannot be assigned to type '() => void' */ -- Gitee From c972b15ac1975469cb8767f81d5eab89829a3563 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Sat, 5 Jul 2025 15:12:42 +0800 Subject: [PATCH 032/107] Fixing type alias as argument causes crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJPCH Description: When type alias is used as argument of callexpression, report CTE. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/checker/ETSchecker.h | 1 - ets2panda/checker/ets/function.cpp | 11 ++-- .../compiler/ets/param_wrong_identifier.ets | 61 +++++++++++++++++++ .../runtime/ets/import_declare_type_alias.ets | 8 +-- 4 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 62c5776c6b..2a61082efb 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -468,7 +468,6 @@ public: bool ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, std::size_t index, TypeRelationFlag flags); bool CheckOptionalLambdaFunction(ir::Expression *argument, Signature *substitutedSig, std::size_t index); - bool ValidateArgumentAsIdentifier(const ir::Identifier *identifier); bool IsValidRestArgument(ir::Expression *argument, Signature *substitutedSig, TypeRelationFlag flags, std::size_t index); bool SetPreferredTypeForArrayArgument(ir::ArrayExpression *arrayExpr, Signature *substitutedSig); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index d2423c24ca..44ae6a83cf 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -385,10 +385,11 @@ bool ETSChecker::CheckOptionalLambdaFunction(ir::Expression *argument, Signature return false; } -bool ETSChecker::ValidateArgumentAsIdentifier(const ir::Identifier *identifier) +static bool IsInvalidArgumentAsIdentifier(varbinder::Scope *scope, const ir::Identifier *identifier) { - auto result = Scope()->Find(identifier->Name()); - return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)); + auto result = scope->Find(identifier->Name()); + return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE | + varbinder::VariableFlags::TYPE_ALIAS)); } static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Expression *argument, Type *paramType, @@ -476,7 +477,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, ClearPreferredTypeForArray(this, argument, paramType, flags, false); - if (argument->IsIdentifier() && ValidateArgumentAsIdentifier(argument->AsIdentifier())) { + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); return false; } @@ -2688,7 +2689,7 @@ bool ETSChecker::ValidateOrderSignatureRequiredParams(Signature *substitutedSig, return false; } - if (argument->IsIdentifier() && ValidateArgumentAsIdentifier(argument->AsIdentifier())) { + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); return false; } diff --git a/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets new file mode 100644 index 0000000000..22b996e74d --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets @@ -0,0 +1,61 @@ +/* + * 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 A { + foo1(a: number) { } + foo2(a: Number) { } + foo3(a: Int) { } + foo4(a: String) { } + static foo5(a: Boolean) { } + static foo6(a: number) { } +} +function foo7(a: number) { } + +function main() { + let a = new A(); + a.foo1(Number); + a.foo2(Number); + a.foo3(Int); + a.foo4(String); + A.foo5(Boolean); + A.foo6(Number); + foo7(Number); + const v1 = Number.isSafeInteger(Number); + try { + const v1 = Number.isSafeInteger(Number); + } catch (e) { } +} + +/* @@? 28:3 Error TypeError: No matching call signature for foo1(Double) */ +/* @@? 28:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 29:3 Error TypeError: No matching call signature for foo2(Double) */ +/* @@? 29:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:3 Error TypeError: No matching call signature for foo3(Int) */ +/* @@? 30:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:10 Error TypeError: Class or interface 'Int' cannot be used as object */ +/* @@? 31:3 Error TypeError: No matching call signature for foo4(String) */ +/* @@? 31:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 31:10 Error TypeError: Class or interface 'String' cannot be used as object */ +/* @@? 32:3 Error TypeError: No matching call signature for foo5(Boolean) */ +/* @@? 32:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 32:10 Error TypeError: Class or interface 'Boolean' cannot be used as object */ +/* @@? 33:3 Error TypeError: No matching call signature for foo6(Double) */ +/* @@? 33:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 34:3 Error TypeError: No matching call signature for foo7(Double) */ +/* @@? 34:8 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 35:14 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 35:35 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 37:16 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 37:37 Error TypeError: Class name can't be the argument of function or method. */ \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/import_declare_type_alias.ets b/ets2panda/test/runtime/ets/import_declare_type_alias.ets index 4f0e85ba1a..f502f6b3b0 100644 --- a/ets2panda/test/runtime/ets/import_declare_type_alias.ets +++ b/ets2panda/test/runtime/ets/import_declare_type_alias.ets @@ -20,9 +20,9 @@ function main() { let type_array_var : type_array = new Array() let type_union_array_var : type_union_array = new Array() let type_array_alias_var : type_array_alias = new Array() - arktest.assertEQ((typeof type_union_var), string); - arktest.assertEQ((typeof type_array_var), object); - arktest.assertEQ((typeof type_union_array_var), object); - arktest.assertEQ((typeof type_array_alias_var), object); + arktest.assertEQ((typeof type_union_var), "string"); + arktest.assertEQ((typeof type_array_var), "object"); + arktest.assertEQ((typeof type_union_array_var), "object"); + arktest.assertEQ((typeof type_array_alias_var), "object"); } -- Gitee From a54e4b321123c853953ef62616a8397c8999dda9 Mon Sep 17 00:00:00 2001 From: oh-rgx Date: Sat, 5 Jul 2025 15:34:54 +0800 Subject: [PATCH 033/107] Fix bigInt operators Issue: #ICK77D Signed-off-by: oh-rgx --- ets2panda/checker/ets/arithmetic.cpp | 1 + .../ets/bigInt_unsigned_right_shift.ets | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index cbe2c38d4e..9e40c07d8f 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -250,6 +250,7 @@ bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::To case lexer::TokenType::PUNCTUATOR_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::KEYW_INSTANCEOF: + case lexer::TokenType::PUNCTUATOR_UNSIGNED_RIGHT_SHIFT: // This is handled in the main CheckBinaryOperator function return false; default: diff --git a/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets b/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets new file mode 100644 index 0000000000..b5b4c1be3a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bigInt_unsigned_right_shift.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + +const v0 = 1516532564n; +const v1 = 213n; + +let v2 = v0 >>> v1; + +/* @@? 19:10 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ -- Gitee From 004233c85a94df73e8f0a14df7053a4820ff82b5 Mon Sep 17 00:00:00 2001 From: anjiaqi Date: Tue, 1 Jul 2025 09:36:02 +0800 Subject: [PATCH 034/107] Fix the security alert Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIY34 Reason: Fix the security alert Description: Fix the security alert Test: ninja all tests Signed-off-by: anjiaqi --- ets2panda/checker/ETSAnalyzer.cpp | 5 +- ets2panda/checker/ETSAnalyzerHelpers.cpp | 8 +++ ets2panda/checker/ETSchecker.cpp | 1 + ets2panda/checker/TSAnalyzer.cpp | 4 ++ ets2panda/checker/ets/aliveAnalyzer.cpp | 1 + ets2panda/checker/ets/arithmetic.cpp | 1 + ets2panda/checker/ets/assignAnalyzer.cpp | 17 +++++-- ets2panda/checker/ets/dynamic.cpp | 5 ++ ets2panda/checker/ets/etsWarningAnalyzer.cpp | 10 ++-- ets2panda/checker/ets/function.cpp | 32 +++++++++--- ets2panda/checker/ets/function_helpers.h | 2 + ets2panda/checker/ets/helpers.cpp | 34 ++++++++++--- ets2panda/checker/ets/object.cpp | 14 ++++-- ets2panda/checker/ets/typeCheckingHelpers.cpp | 27 ++++++++-- ets2panda/checker/ets/typeCreation.cpp | 13 ++++- ets2panda/checker/ets/typeRelationContext.cpp | 1 + ets2panda/checker/ets/utilityTypeHandlers.cpp | 39 +++++++++++---- ets2panda/checker/ts/destructuringContext.cpp | 4 ++ ets2panda/checker/ts/function.cpp | 10 +++- ets2panda/checker/ts/helpers.cpp | 4 +- ets2panda/checker/ts/object.cpp | 4 ++ ets2panda/checker/ts/typeCreation.cpp | 6 ++- .../checker/types/ets/etsFunctionType.cpp | 20 +++++--- ets2panda/checker/types/ets/etsObjectType.cpp | 5 ++ .../types/ets/etsPartialTypeParameter.cpp | 9 +++- ets2panda/checker/types/ets/etsTupleType.cpp | 1 + ets2panda/checker/types/ets/etsTupleType.h | 5 +- .../checker/types/ets/etsTypeParameter.cpp | 1 + ets2panda/checker/types/ets/etsUnionType.cpp | 2 + ets2panda/checker/types/signature.cpp | 5 +- ets2panda/checker/types/signature.h | 1 + ets2panda/checker/types/ts/interfaceType.cpp | 3 +- .../checker/types/ts/objectDescriptor.cpp | 4 +- ets2panda/checker/types/ts/unionType.cpp | 4 +- ets2panda/checker/types/typeRelation.cpp | 2 + ets2panda/parser/ASparser.cpp | 27 ++++++++++ ets2panda/parser/ETSFormattedParser.cpp | 4 ++ ets2panda/parser/ETSparser.cpp | 43 ++++++++++++++++ ets2panda/parser/ETSparserAnnotations.cpp | 18 +++++-- ets2panda/parser/ETSparserClasses.cpp | 33 ++++++++++--- ets2panda/parser/ETSparserEnums.cpp | 1 + ets2panda/parser/ETSparserExpressions.cpp | 10 ++++ ets2panda/parser/ETSparserJsDocInfo.cpp | 7 ++- ets2panda/parser/ETSparserNamespaces.cpp | 2 + ets2panda/parser/ETSparserStatements.cpp | 2 + ets2panda/parser/ETSparserTypes.cpp | 10 ++++ ets2panda/parser/TSparser.cpp | 24 ++++++++- .../parser/context/classPrivateContext.cpp | 10 ++-- ets2panda/parser/expressionParser.cpp | 49 +++++++++++++++++++ ets2panda/parser/expressionTSParser.cpp | 8 +++ ets2panda/parser/parserImpl.cpp | 18 ++++++- ets2panda/parser/program/program.cpp | 3 +- ets2panda/parser/statementParser.cpp | 40 +++++++++++++++ ets2panda/parser/statementTSParser.cpp | 6 +++ 54 files changed, 538 insertions(+), 81 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index b15d9a5313..dc362f2668 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -167,6 +167,7 @@ checker::Type *ETSAnalyzer::Check(ir::ClassStaticBlock *st) const static void HandleNativeAndAsyncMethods(ETSChecker *checker, ir::MethodDefinition *node) { auto *scriptFunc = node->Function(); + ES2PANDA_ASSERT(scriptFunc != nullptr); if (node->IsNative() && !node->IsConstructor() && !scriptFunc->IsSetter()) { if (scriptFunc->ReturnTypeAnnotation() == nullptr) { checker->LogError(diagnostic::NATIVE_WITHOUT_RETURN, {}, scriptFunc->Start()); @@ -479,6 +480,7 @@ static bool CheckArrayElementType(ETSChecker *checker, T *newArrayInstanceExpr) ES2PANDA_ASSERT(newArrayInstanceExpr != nullptr); checker::Type *elementType = newArrayInstanceExpr->TypeReference()->GetType(checker)->MaybeBaseTypeOfGradualType(); + ES2PANDA_ASSERT(elementType != nullptr); if (elementType->IsETSPrimitiveType()) { return true; } @@ -3114,7 +3116,7 @@ checker::Type *ETSAnalyzer::Check(ir::AnnotationUsage *st) const return ReturnTypeForStatement(st); } - if (st->Properties().size() == 1 && + if (st->Properties().size() == 1 && st->Properties().at(0)->AsClassProperty()->Id() != nullptr && st->Properties().at(0)->AsClassProperty()->Id()->Name() == compiler::Signatures::ANNOTATION_KEY_VALUE) { checker->CheckSinglePropertyAnnotation(st, annoDecl); fieldMap.clear(); @@ -3376,6 +3378,7 @@ bool ETSAnalyzer::CheckInferredFunctionReturnType(ir::ReturnStatement *st, ir::S // Case when function's return type is defined explicitly: if (st->argument_ == nullptr) { + ES2PANDA_ASSERT(funcReturnType != nullptr); if (!funcReturnType->MaybeBaseTypeOfGradualType()->IsETSVoidType() && funcReturnType != checker->GlobalVoidType() && !funcReturnType->MaybeBaseTypeOfGradualType()->IsETSAsyncFuncReturnType()) { diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 021f906c1a..9e04b6d31d 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -57,6 +57,7 @@ void CheckExtensionIsShadowedInCurrentClassOrInterface(checker::ETSChecker *chec const auto *const funcType = methodVariable->TsType()->AsETSFunctionType(); for (auto *funcSignature : funcType->CallSignatures()) { + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(funcSignature->ReturnType()); if (!checker->Relation()->SignatureIsSupertypeOf(signature, funcSignature) && !checker->HasSameAssemblySignature(signature, funcSignature)) { @@ -149,6 +150,7 @@ void CheckExtensionMethod(checker::ETSChecker *checker, ir::ScriptFunction *exte checker::SignatureInfo *originalExtensionSigInfo = checker->ProgramAllocator()->New( extensionFunc->Signature()->GetSignatureInfo(), checker->ProgramAllocator()); + ES2PANDA_ASSERT(originalExtensionSigInfo != nullptr); originalExtensionSigInfo->minArgCount -= 1U; originalExtensionSigInfo->params.erase(originalExtensionSigInfo->params.begin()); checker::Signature *originalExtensionSignature = @@ -220,6 +222,7 @@ void DoBodyTypeChecking(ETSChecker *checker, ir::MethodDefinition *node, ir::Scr if (scriptFunc->ReturnTypeAnnotation() == nullptr) { if (scriptFunc->IsAsyncFunc()) { auto returnType = checker->CreateETSAsyncFuncReturnTypeFromBaseType(scriptFunc->Signature()->ReturnType()); + ES2PANDA_ASSERT(returnType != nullptr); scriptFunc->Signature()->SetReturnType(returnType->PromiseType()); for (auto &returnStatement : scriptFunc->ReturnStatements()) { returnStatement->SetReturnType(checker, returnType); @@ -248,6 +251,7 @@ void ComposeAsyncImplFuncReturnType(ETSChecker *checker, ir::ScriptFunction *scr auto *returnType = checker->ProgramAllocNode( checker->ProgramAllocNode(objectId, nullptr, nullptr, checker->ProgramAllocator()), checker->ProgramAllocator()); + ES2PANDA_ASSERT(returnType != nullptr); objectId->SetParent(returnType->Part()); returnType->Part()->SetParent(returnType); returnType->SetTsType(checker->ProgramAllocator()->New(checker->ProgramAllocator(), @@ -317,6 +321,7 @@ void CheckIteratorMethodReturnType(ETSChecker *checker, ir::ScriptFunction *scri returnType = checker->GetApparentType(returnType->AsETSTypeParameter()->GetConstraintType()); } + ES2PANDA_ASSERT(returnType != nullptr); if (returnType->IsETSObjectType() && HasIteratorInterface(returnType->AsETSObjectType())) { return; } @@ -672,6 +677,7 @@ checker::Type *InferReturnType(ETSChecker *checker, ir::ScriptFunction *containi auto typeAnnotation = arrowFunc->CreateTypeAnnotation(checker); auto *argumentType = arrowFunc->TsType(); + ES2PANDA_ASSERT(typeAnnotation != nullptr); funcReturnType = typeAnnotation->GetType(checker); if (!checker::AssignmentContext(checker->Relation(), arrowFunc, argumentType, funcReturnType, stArgument->Start(), std::nullopt, @@ -744,6 +750,7 @@ checker::Type *ProcessReturnStatements(ETSChecker *checker, ir::ScriptFunction * checker::Type *argumentType = checker->GetNonConstantType(stArgument->Check(checker)); // previous return statement(s) don't have any value + ES2PANDA_ASSERT(argumentType != nullptr); if (funcReturnType->IsETSVoidType() && !argumentType->IsETSVoidType()) { checker->LogError(diagnostic::MIXED_VOID_NONVOID, {}, stArgument->Start()); return funcReturnType; @@ -773,6 +780,7 @@ bool CheckReturnTypeNecessity(ir::MethodDefinition *node) auto *scriptFunc = node->Function(); needReturnType &= (node->IsNative() || node->IsDeclare()); needReturnType &= !node->IsConstructor(); + ES2PANDA_ASSERT(scriptFunc != nullptr); needReturnType &= !scriptFunc->IsSetter(); return needReturnType; } diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index abf418beae..c301c826b3 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -697,6 +697,7 @@ ETSObjectType *ETSChecker::GlobalBuiltinBoxType(Type *contents) default: { auto *base = AsETSObjectType(&GlobalTypesHolder::GlobalBoxBuiltinType); auto substitution = Substitution {}; + ES2PANDA_ASSERT(base != nullptr); substitution.emplace(base->TypeArguments()[0]->AsETSTypeParameter(), contents); return base->Substitute(Relation(), &substitution); } diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index cfaad3f534..c353155e2c 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -107,6 +107,7 @@ checker::Type *TSAnalyzer::Check(ir::TSMethodSignature *node) const } returnType->Check(checker); + ES2PANDA_ASSERT(callSignature != nullptr); callSignature->SetReturnType(returnType->GetType(checker)); return nullptr; @@ -787,6 +788,7 @@ void TSAnalyzer::CheckNonComputed(checker::ObjectDescriptor *desc, ir::Expressio auto *memberVar = varbinder::Scope::CreateVar(checker->Allocator(), propName, flags, it); + ES2PANDA_ASSERT(memberVar != nullptr); if (inConstContext) { memberVar->AddFlag(varbinder::VariableFlags::READONLY); } else { @@ -1342,6 +1344,7 @@ static void CheckSimpleVariableDeclaration(checker::TSChecker *checker, ir::Vari initializerType = checker->GetBaseTypeOfLiteralType(initializerType); } + ES2PANDA_ASSERT(initializerType != nullptr); if (initializerType->IsNullType()) { checker->ThrowTypeError( {"Cannot infer type for variable '", declarator->Id()->AsIdentifier()->Name(), "'."}, @@ -1729,6 +1732,7 @@ static void AddEnumValueDeclaration(checker::TSChecker *checker, double number, if (res == nullptr) { auto *decl = checker->Allocator()->New(memberStr); + ES2PANDA_ASSERT(decl != nullptr); decl->BindNode(variable->Declaration()->Node()); enumScope->AddDecl(checker->Allocator(), decl, ScriptExtension::TS); res = enumScope->FindLocal(memberStr, varbinder::ResolveBindingOptions::BINDINGS); diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index a4b3ed1b9b..7ac350c66e 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -235,6 +235,7 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); if (func->Body() == nullptr || func->IsProxy()) { return; } diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index cbe2c38d4e..376bd55957 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -933,6 +933,7 @@ Type *ETSChecker::CheckBinaryOperatorNullishCoalescing(ir::Expression *left, ir: LogError(diagnostic::COALESCE_NOT_REF, {}, pos); } leftType = GetNonNullishType(leftType); + ES2PANDA_ASSERT(leftType != nullptr); if (leftType->IsTypeError()) { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index d5d379b49b..1bf641755b 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -536,7 +536,9 @@ static bool IsInitialConstructor(const ir::AstNode *node) return false; } - const auto funcBody = node->AsMethodDefinition()->Function()->Body()->AsBlockStatement(); + const auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + const auto funcBody = func->Body()->AsBlockStatement(); return !(!funcBody->Statements().empty() && funcBody->Statements()[0]->IsExpressionStatement() && funcBody->Statements()[0]->AsExpressionStatement()->GetExpression()->IsCallExpression() && @@ -551,7 +553,7 @@ static bool IsInitialConstructor(const ir::AstNode *node) void AssignAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) { auto *func = methodDef->Function(); - + ES2PANDA_ASSERT(func != nullptr); if (func->Body() == nullptr || func->IsProxy()) { return; } @@ -1204,8 +1206,11 @@ util::StringView AssignAnalyzer::GetVariableType(const ir::AstNode *node) const util::StringView AssignAnalyzer::GetVariableName(const ir::AstNode *node) const { switch (node->Type()) { - case ir::AstNodeType::CLASS_PROPERTY: - return node->AsClassProperty()->Id()->Name(); + case ir::AstNodeType::CLASS_PROPERTY: { + const ir::Identifier *identifier = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(identifier != nullptr); + return identifier->Name(); + } case ir::AstNodeType::VARIABLE_DECLARATOR: return node->AsVariableDeclarator()->Id()->AsIdentifier()->Name(); default: @@ -1277,7 +1282,9 @@ varbinder::Variable *AssignAnalyzer::GetBoundVariable(const ir::AstNode *node) varbinder::Variable *ret = nullptr; if (node->IsClassProperty()) { - ret = node->AsClassProperty()->Id()->Variable(); + const ir::Identifier *identifier = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(identifier != nullptr); + ret = identifier->Variable(); } else if (node->IsVariableDeclarator()) { ret = node->AsVariableDeclarator()->Id()->AsIdentifier()->Variable(); } else { diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index e5530fc812..a7622ce25b 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -48,6 +48,7 @@ namespace ark::es2panda::checker { void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) { auto scope = compiler::NearestScope(node); + ES2PANDA_ASSERT(scope != nullptr); if (scope->IsGlobalScope()) { // NOTE(aleksisch): All classes are contained in ETSGlobal class scope (not just Global scope), // however it's parent is ETSModule. It should be fixed @@ -71,6 +72,7 @@ void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) void ProcessScopesNode(ETSChecker *checker, ir::AstNode *node) { auto *scope = compiler::NearestScope(node); + ES2PANDA_ASSERT(scope != nullptr); if (scope->IsGlobalScope()) { // NOTE(aleksisch): All classes are contained in ETSGlobal scope, // however it's parent is ETSModule (not ETSGlobal). It should be fixed @@ -117,6 +119,7 @@ std::pair ETSChecker::CreateStaticScript ir::ModifierFlags::STATIC, }); // clang-format on + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); return std::make_pair(func, id); @@ -143,6 +146,7 @@ std::pair ETSChecker::CreateScriptFuncti ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, ir::ModifierFlags::PUBLIC}); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(id); return std::make_pair(func, id); @@ -159,6 +163,7 @@ ir::ClassStaticBlock *ETSChecker::CreateClassStaticInitializer(const ClassInitia // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *staticBlock = ProgramAllocNode(funcExpr, ProgramAllocator()); + ES2PANDA_ASSERT(staticBlock != nullptr); staticBlock->AddModifier(ir::ModifierFlags::STATIC); return staticBlock; diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.cpp b/ets2panda/checker/ets/etsWarningAnalyzer.cpp index fc451700cc..20f01dae13 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.cpp +++ b/ets2panda/checker/ets/etsWarningAnalyzer.cpp @@ -103,8 +103,10 @@ void ETSWarningAnalyzer::AnalyzeClassMethodForFinalModifier(const ir::MethodDefi } const util::StringView bodyMethodName = ETSChecker::GetSignatureFromMethodDefinition(bodyPart->AsMethodDefinition())->Function()->Id()->Name(); + const auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); if (bodyPart->IsOverride() && bodyMethodName != compiler::Signatures::CTOR && - bodyMethodName == methodDef->Function()->Id()->Name()) { + bodyMethodName == func->Id()->Name()) { suggestFinal = false; break; } @@ -212,9 +214,9 @@ void ETSWarningAnalyzer::ETSWarningsProhibitTopLevelStatements(const ir::AstNode itBody->AsMethodDefinition()->Id()->Name() != compiler::Signatures::INIT_METHOD) { continue; } - - for (const auto *statement : - itBody->AsMethodDefinition()->Function()->Body()->AsBlockStatement()->Statements()) { + const auto *func = itBody->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + for (const auto *statement : func->Body()->AsBlockStatement()->Statements()) { if (program_->NodeContainsETSNolint(statement, ETSWarnings::ETS_PROHIBIT_TOP_LEVEL_STATEMENTS)) { continue; } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index c31ff61607..aadceefbdf 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -91,6 +91,7 @@ bool ETSChecker::EnhanceSubstitutionForReadonly(const ArenaVector &typeP bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution) { + ES2PANDA_ASSERT(argumentType != nullptr); if (argumentType->IsETSPrimitiveType()) { argumentType = MaybeBoxInRelation(argumentType); } @@ -442,6 +443,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, auto const paramType = GetNonNullishType(substitutedSig->Params()[index]->TsType())->MaybeBaseTypeOfGradualType(); if (argument->IsObjectExpression()) { + ES2PANDA_ASSERT(paramType != nullptr); if (!paramType->IsETSObjectType()) { return false; } @@ -1077,6 +1079,7 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( for (auto *sig : signatures) { auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + ES2PANDA_ASSERT(sigParamType != nullptr); if (!sigParamType->IsETSFunctionType()) { continue; } @@ -1409,7 +1412,9 @@ static bool CollectOverload(checker::ETSChecker *checker, ir::MethodDefinition * currentFunc->Function()->Id()->SetVariable(currentFunc->Id()->Variable()); checker->BuildFunctionSignature(currentFunc->Function(), method->IsConstructor()); if (currentFunc->Function()->Signature() == nullptr) { - method->Id()->Variable()->SetTsType(checker->GlobalTypeError()); + auto *methodId = method->Id(); + ES2PANDA_ASSERT(methodId != nullptr); + methodId->Variable()->SetTsType(checker->GlobalTypeError()); return false; } @@ -1454,11 +1459,12 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) if (method->TsType() != nullptr) { return method->TsType()->AsETSFunctionType(); } - - method->Function()->Id()->SetVariable(method->Id()->Variable()); + auto *methodId = method->Id(); + method->Function()->Id()->SetVariable(methodId->Variable()); BuildFunctionSignature(method->Function(), method->IsConstructor()); if (method->Function()->Signature() == nullptr) { - return method->Id()->Variable()->SetTsType(GlobalTypeError()); + ES2PANDA_ASSERT(methodId != nullptr); + return methodId->Variable()->SetTsType(GlobalTypeError()); } auto *funcType = BuildMethodType(method->Function()); method->InitializeOverloadInfo(); @@ -1472,7 +1478,7 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) LogDiagnostic(diagnostic::FUNCTION_ASM_SIG_COLLISION, {std::string(funcType->Name())}, method->Start()); } - return method->Id()->Variable()->SetTsType(funcType); + return methodId->Variable()->SetTsType(funcType); } bool ETSChecker::CheckIdenticalOverloads(ETSFunctionType *func, ETSFunctionType *overload, @@ -1597,6 +1603,7 @@ SignatureInfo *ETSChecker::ComposeSignatureInfo(ir::TSTypeParameterDeclaration * if (typeParams != nullptr) { auto [typeParamTypes, ok] = CreateUnconstrainedTypeParameters(typeParams); + ES2PANDA_ASSERT(signatureInfo != nullptr); signatureInfo->typeParams = std::move(typeParamTypes); if (ok) { AssignTypeParameterConstraints(typeParams); @@ -1658,6 +1665,7 @@ void ETSChecker::ValidateMainSignature(ir::ScriptFunction *func) void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstructSig) { + ES2PANDA_ASSERT(func != nullptr); bool isArrow = func->IsArrow(); // note(Ekko): For extenal function overload, need to not change ast tree, for arrow type, need perferred type. if (func->Signature() != nullptr && !isArrow) { @@ -1708,6 +1716,7 @@ void ETSChecker::BuildFunctionSignature(ir::ScriptFunction *func, bool isConstru checker::ETSFunctionType *ETSChecker::BuildMethodType(ir::ScriptFunction *func) { ES2PANDA_ASSERT(!func->IsArrow()); + ES2PANDA_ASSERT(func != nullptr); auto *nameVar = func->Id()->Variable(); ETSFunctionType *funcType = CreateETSMethodType(nameVar->Name(), {{func->Signature()}, ProgramAllocator()->Adapter()}); @@ -1726,7 +1735,7 @@ Signature *ETSChecker::CheckEveryAbstractSignatureIsOverridden(ETSFunctionType * for (auto sourceSig : source->CallSignatures()) { if ((*targetSig)->Function()->Id()->Name() == sourceSig->Function()->Id()->Name() && Relation()->SignatureIsSupertypeOf(*targetSig, sourceSig)) { - target->CallSignatures().erase(targetSig); + targetSig = target->CallSignatures().erase(targetSig); isOverridden = true; break; } @@ -1963,6 +1972,7 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) void ETSChecker::CheckOverride(Signature *signature) { auto *owner = signature->Owner(); + ES2PANDA_ASSERT(owner != nullptr); bool isOverriding = false; if (!owner->HasObjectFlag(ETSObjectFlags::CLASS | ETSObjectFlags::INTERFACE)) { @@ -2177,7 +2187,9 @@ std::string ETSChecker::GetAsyncImplName(const util::StringView &name) std::string ETSChecker::GetAsyncImplName(ir::MethodDefinition *asyncMethod) { - ir::Identifier *asyncName = asyncMethod->Function()->Id(); + ir::ScriptFunction *scriptFunc = asyncMethod->Function(); + CHECK_NOT_NULL(scriptFunc); + ir::Identifier *asyncName = scriptFunc->Id(); ES2PANDA_ASSERT_POS(asyncName != nullptr, asyncMethod->Start()); return GetAsyncImplName(asyncName->Name()); } @@ -2213,6 +2225,7 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: if (body != nullptr && body->IsBlockStatement()) { body->AsBlockStatement()->SetScope(scope); } + ES2PANDA_ASSERT(scope != nullptr); scope->BindNode(func); paramScope->BindNode(func); scope->BindParamScope(paramScope); @@ -2245,7 +2258,9 @@ varbinder::FunctionParamScope *ETSChecker::CopyParams( for (auto *const it : params) { auto *const paramOld = it->AsETSParameterExpression(); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *const paramNew = paramOld->Clone(ProgramAllocator(), paramOld->Parent())->AsETSParameterExpression(); + auto *typeOld = paramOld->Clone(ProgramAllocator(), paramOld->Parent()); + ES2PANDA_ASSERT(typeOld != nullptr); + auto *const paramNew = typeOld->AsETSParameterExpression(); varbinder::Variable *var = VarBinder()->AddParamDecl(paramNew); Type *paramType = paramOld->Variable()->TsType(); @@ -2390,6 +2405,7 @@ ArenaVector ETSChecker::ExtendArgumentsWithFakeLamda(ir::CallE ArenaVector statements(ProgramAllocator()->Adapter()); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); + ES2PANDA_ASSERT(body != nullptr); body->SetScope(funcScope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) diff --git a/ets2panda/checker/ets/function_helpers.h b/ets2panda/checker/ets/function_helpers.h index 7c22e2f83b..7730c65f76 100644 --- a/ets2panda/checker/ets/function_helpers.h +++ b/ets2panda/checker/ets/function_helpers.h @@ -54,6 +54,7 @@ namespace ark::es2panda::checker { static Type *MaybeBoxedType(ETSChecker *checker, Type *type, ir::Expression *expr) { + ES2PANDA_ASSERT(type != nullptr); if (!type->IsETSPrimitiveType()) { return type; } @@ -77,6 +78,7 @@ static void InferUntilFail(Signature const *const signature, const ArenaVectorAddStatus(checker::CheckerStatus::IN_TYPE_INFER); // some ets lib files require type infer from arg index 0,1,... , not fit to build graph + ES2PANDA_ASSERT(substitution != nullptr); while (anyChange && substitution->size() < sigParams.size()) { anyChange = false; for (size_t ix = 0; ix < arguments.size(); ++ix) { diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index cbe5c880a3..1885f12c22 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -62,6 +62,7 @@ varbinder::Variable *ETSChecker::FindVariableInGlobal(const ir::Identifier *cons bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) { + CHECK_NOT_NULL(var); if (var->HasFlag(varbinder::VariableFlags::METHOD)) { return var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); } @@ -781,6 +782,7 @@ static void CheckAssignForDeclare(ir::Identifier *ident, ir::TypeNode *typeAnnot return; } const bool isConst = (flags & ir::ModifierFlags::CONST) != 0; + ES2PANDA_ASSERT(init != nullptr); bool numberLiteralButNotBigInt = init->IsNumberLiteral() && !init->IsBigIntLiteral(); bool multilineLiteralWithNoEmbedding = init->IsTemplateLiteral() && init->AsTemplateLiteral()->Expressions().empty(); @@ -877,6 +879,7 @@ static void CheckRecordType(ir::Expression *init, checker::Type *annotationType, checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::TypeNode *typeAnnotation, ir::Expression *init, ir::ModifierFlags const flags) { + ES2PANDA_ASSERT(ident != nullptr); varbinder::Variable *const bindingVar = ident->Variable(); checker::Type *annotationType = nullptr; @@ -1784,6 +1787,7 @@ void ETSChecker::SetPropertiesForModuleObject(checker::ETSObjectType *moduleObjT parser::Program *program = SelectEntryOrExternalProgram(static_cast(VarBinder()), importPath); // Check imported properties before assigning them to module object + ES2PANDA_ASSERT(program != nullptr); if (!program->IsASTChecked()) { // NOTE: helps to avoid endless loop in case of recursive imports that uses all bindings program->SetASTChecked(); @@ -2382,7 +2386,7 @@ ETSObjectType *ETSChecker::GetRelevantArgumentedTypeFromChild(ETSObjectType *con auto *relevantType = CreateETSObjectType(child->GetDeclNode(), child->ObjectFlags()); ArenaVector params = child->TypeArguments(); - + ES2PANDA_ASSERT(relevantType != nullptr); relevantType->SetTypeArguments(std::move(params)); relevantType->SetEnclosingType(child->EnclosingType()); relevantType->SetSuperType(child->SuperType()); @@ -2406,6 +2410,7 @@ void ETSChecker::EmplaceSubstituted(Substitution *substitution, ETSTypeParameter { // *only* reference type may be substituted, no exceptions ES2PANDA_ASSERT(typeArg->IsETSReferenceType()); + ES2PANDA_ASSERT(substitution != nullptr); substitution->emplace(tparam, typeArg); } @@ -2474,7 +2479,9 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) if (type->ReturnType()->IsTSThisType()) { type->Params()[0]->AsETSParameterExpression()->TypeAnnotation()->TsType()->ToString(ss, true); } else { - type->ReturnType()->GetType(this)->ToString(ss, true); + auto *returnType = type->ReturnType()->GetType(this); + ES2PANDA_ASSERT(returnType != nullptr); + returnType->ToString(ss, true); } ss << "extensionFunction;"; } else { @@ -2699,6 +2706,7 @@ ir::ClassProperty *ETSChecker::ClassPropToImplementationProp(ir::ClassProperty * classProp->AddModifier(ir::ModifierFlags::PRIVATE); auto *fieldDecl = ProgramAllocator()->New(classProp->Key()->AsIdentifier()->Name()); + ES2PANDA_ASSERT(fieldDecl != nullptr); fieldDecl->BindNode(classProp); auto fieldVar = scope->InstanceFieldScope()->AddDecl(ProgramAllocator(), fieldDecl, ScriptExtension::ETS); @@ -2801,6 +2809,7 @@ static ir::BlockStatement *GenGetterSetterBodyHelper(ETSChecker *checker, ArenaV return nullptr; } auto *body = checker->ProgramAllocNode(checker->ProgramAllocator(), std::move(stmts)); + ES2PANDA_ASSERT(body != nullptr); body->SetScope(functionScope); return body; } @@ -2876,8 +2885,10 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty method->Id()->SetMutator(); method->SetRange(field->Range()); + auto *methodId = method->Id(); + CHECK_NOT_NULL(methodId); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - method->Function()->SetIdent(method->Id()->Clone(checker->ProgramAllocator(), nullptr)); + method->Function()->SetIdent(methodId->Clone(checker->ProgramAllocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); method->SetVariable(var); method->SetParent(field->Parent()); @@ -2935,19 +2946,21 @@ void ETSChecker::SetupGetterSetterFlags(ir::ClassProperty *originalProp, ETSObje method->TsType()->AddTypeFlag(tflag); method->Variable()->SetTsType(method->TsType()); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); if (((originalProp->Modifiers() & mflag) != 0U)) { - method->Function()->AddModifier(ir::ModifierFlags::OVERRIDE); + func->AddModifier(ir::ModifierFlags::OVERRIDE); } if (inExternal && !getProgram(originalProp)->IsGenAbcForExternal()) { - method->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + func->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } if (originalProp->IsDeclare()) { method->AddModifier(ir::ModifierFlags::DECLARE); - method->Function()->AddModifier(ir::ModifierFlags::DECLARE); + func->AddModifier(ir::ModifierFlags::DECLARE); } - this->CheckOverride(method->Function()->Signature()); + this->CheckOverride(func->Signature()); method->SetParent(classDef); classType->AddProperty(method->Variable()->AsLocalVariable()); } @@ -3092,6 +3105,7 @@ void ETSChecker::ImportNamespaceObjectTypeAddReExportType(ir::ETSImportDeclarati if (reExportType->IsTypeError()) { continue; } + ES2PANDA_ASSERT(lastObjectType != nullptr); lastObjectType->AddReExports(reExportType->AsETSObjectType()); for (auto node : importDecl->Specifiers()) { if (node->IsImportSpecifier()) { @@ -3125,6 +3139,7 @@ Type *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration *importD auto *rootDecl = ProgramAllocator()->New(moduleName); varbinder::LocalVariable *rootVar = ProgramAllocator()->New(rootDecl, varbinder::VariableFlags::NONE); + ES2PANDA_ASSERT(rootVar != nullptr); rootVar->SetTsType(moduleObjectType); ImportNamespaceObjectTypeAddReExportType(importDecl, moduleObjectType, ident); @@ -3139,7 +3154,9 @@ ETSChecker::NamedAccessMeta ETSChecker::FormNamedAccessMetadata(varbinder::Varia { const auto *field = prop->Declaration()->Node()->AsClassProperty(); const auto *owner = field->Parent()->AsClassDefinition(); - return {owner->TsType()->AsETSObjectType(), field->TsType(), field->Id()->Name()}; + auto *fieldId = field->Id(); + CHECK_NOT_NULL(fieldId); + return {owner->TsType()->AsETSObjectType(), field->TsType(), fieldId->Name()}; } void ETSChecker::ETSObjectTypeDeclNode(ETSChecker *checker, ETSObjectType *const objectType) @@ -3168,6 +3185,7 @@ ir::CallExpression *ETSChecker::CreateExtensionAccessorCall(ETSChecker *checker, // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) callExpr = checker->ProgramAllocNode(expr, std::move(args), nullptr, false, false); } + ES2PANDA_ASSERT(callExpr != nullptr); callExpr->SetRange(expr->Range()); return callExpr->AsCallExpression(); } diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index ad7a332f38..ced96af24f 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -215,6 +215,7 @@ bool ETSChecker::ComputeSuperType(ETSObjectType *type) void ETSChecker::ValidateImplementedInterface(ETSObjectType *type, Type *interface, std::unordered_set *extendsSet, const lexer::SourcePosition &pos) { + ES2PANDA_ASSERT(interface != nullptr); interface = interface->MaybeBaseTypeOfGradualType(); if (interface->IsETSObjectType() && interface->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::CLASS)) { LogError(diagnostic::INTERFACE_EXTENDS_CLASS, {}, pos); @@ -428,7 +429,7 @@ ETSTypeParameter *ETSChecker::SetUpParameterType(ir::TSTypeParameter *const para } auto *const paramType = CreateTypeParameter(); - + ES2PANDA_ASSERT(paramType != nullptr); paramType->AddTypeFlag(TypeFlag::GENERIC); paramType->SetDeclNode(param); paramType->SetVariable(param->Variable()); @@ -564,6 +565,7 @@ ETSObjectType *ETSChecker::BuildAnonymousClassProperties(ir::ClassDefinition *cl { auto classType = CreateETSObjectType(classDef, checker::ETSObjectFlags::CLASS); classDef->SetTsType(classType); + ES2PANDA_ASSERT(classType != nullptr); classType->SetSuperType(superType); classType->AddObjectFlag(checker::ETSObjectFlags::RESOLVED_SUPER); @@ -589,6 +591,7 @@ static void ResolveDeclaredFieldsOfObject(ETSChecker *checker, const ETSObjectTy } } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectType *type, varbinder::ClassScope *scope) { for (auto &[_, it] : scope->InstanceMethodScope()->Bindings()) { @@ -596,6 +599,7 @@ static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectT if (it->Declaration()->Node()->IsMethodDefinition()) { auto *method = it->Declaration()->Node()->AsMethodDefinition(); auto *function = method->Function(); + ES2PANDA_ASSERT(function != nullptr); if (function->IsProxy()) { continue; } @@ -919,6 +923,7 @@ void ETSChecker::CheckFunctionRedeclarationInInterface(ETSObjectType *classType, if (sig == sigFunc) { return; } + ES2PANDA_ASSERT(sigFunc != nullptr); if (sigFunc->Function()->Id()->Name() == sig->Function()->Id()->Name()) { if (classType->IsSameBasedGeneric(Relation(), sig->Owner())) { return; @@ -938,6 +943,7 @@ static void CallRedeclarationCheckForCorrectSignature(ir::MethodDefinition *meth ETSObjectType *classType, ETSChecker *checker) { ir::ScriptFunction *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); if (!func->IsAbstract()) { auto *sigFunc = funcType->FindSignature(func); checker->CheckFunctionRedeclarationInInterface(classType, similarSignatures, sigFunc); @@ -1812,6 +1818,7 @@ void ETSChecker::CheckCyclicConstructorCall(Signature *signature) ETSObjectType *ETSChecker::CheckExceptionOrErrorType(checker::Type *type, const lexer::SourcePosition pos) { + ES2PANDA_ASSERT(type != nullptr); if (!type->IsETSObjectType() || (!Relation()->IsAssignableTo(type, GlobalBuiltinExceptionType()) && !Relation()->IsAssignableTo(type, GlobalBuiltinErrorType()))) { LogError(diagnostic::CATCH_OR_THROW_OF_INVALID_TYPE, @@ -2324,7 +2331,8 @@ void ETSChecker::WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *co !parent->AsMethodDefinition()->Function()->IsSetter()))) { parent = parent->Parent(); } - if (parent != nullptr && ident->Name() == parent->AsMethodDefinition()->Function()->Id()->Name()) { + if (parent != nullptr && parent->AsMethodDefinition()->Function() != nullptr && + ident->Name() == parent->AsMethodDefinition()->Function()->Id()->Name()) { if (parent->AsMethodDefinition()->Function()->IsGetter()) { LogDiagnostic(diagnostic::GETTER_LOOP, memberExpr->Property()->AsIdentifier()->Start()); } else { @@ -2568,7 +2576,7 @@ Type *ETSChecker::GetApparentType(Type *type) apparentTypes.insert({res, res}); return res; }; - + ES2PANDA_ASSERT(type != nullptr); if (type->IsGradualType()) { return cached(type->AsGradualType()->GetBaseType()); } diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index f2a5fd239c..463673cbce 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -414,6 +414,7 @@ bool ETSChecker::IsConstantExpression(ir::Expression *expr, Type *type) Type *ETSChecker::GetNonConstantType(Type *type) { + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSStringType()) { return GlobalBuiltinETSStringType(); } @@ -471,7 +472,9 @@ Type *ETSChecker::GetTypeOfSetterGetter(varbinder::Variable *const var) { auto *propType = var->TsType()->AsETSFunctionType(); if (propType->HasTypeFlag(checker::TypeFlag::GETTER)) { - return propType->FindGetter()->ReturnType(); + auto *getter = propType->FindGetter(); + ES2PANDA_ASSERT(getter != nullptr); + return getter->ReturnType(); } return propType->FindSetter()->Params()[0]->TsType(); @@ -511,7 +514,9 @@ void ETSChecker::IterateInVariableContext(varbinder::Variable *const var) if (iter->IsMethodDefinition()) { auto *methodDef = iter->AsMethodDefinition(); ES2PANDA_ASSERT(methodDef->TsType()); - Context().SetContainingSignature(methodDef->Function()->Signature()); + auto *func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); + Context().SetContainingSignature(func->Signature()); } else if (iter->IsClassDefinition()) { auto *classDef = iter->AsClassDefinition(); Type *containingClass {}; @@ -666,7 +671,9 @@ Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable * switch (auto node = prop->Declaration()->Node(); node->Type()) { case ir::AstNodeType::CLASS_PROPERTY: { - auto baseProp = node->AsClassProperty()->Id()->Variable(); + auto *id = node->AsClassProperty()->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto baseProp = id->Variable(); if (baseProp == prop) { return nullptr; } @@ -686,6 +693,7 @@ Type *ETSChecker::GuaranteedTypeForUncheckedPropertyAccess(varbinder::Variable * // Determine if substituted method cast requires cast from erased type Type *ETSChecker::GuaranteedTypeForUncheckedCallReturn(Signature *sig) { + ES2PANDA_ASSERT(sig != nullptr); ES2PANDA_ASSERT(sig->HasFunction()); if (sig->HasSignatureFlag(SignatureFlags::THIS_RETURN_TYPE)) { return sig->ReturnType(); @@ -704,6 +712,7 @@ Type *ETSChecker::ResolveUnionUncheckedType(ArenaVector &&appar return nullptr; } auto *unionType = CreateETSUnionType(std::move(apparentTypes)); + ES2PANDA_ASSERT(unionType != nullptr); if (unionType->IsETSUnionType()) { checker::Type *typeLUB = unionType->AsETSUnionType()->GetAssemblerLUB(); return typeLUB; @@ -808,6 +817,7 @@ Type *ETSChecker::GetTypeFromTypeAliasReference(varbinder::Variable *var) typeAliasType = CreateETSTypeAliasType(aliasTypeNode->Id()->Name(), aliasTypeNode); if (aliasTypeNode->TypeParams() != nullptr) { auto [typeParamTypes, ok] = CreateUnconstrainedTypeParameters(aliasTypeNode->TypeParams()); + ES2PANDA_ASSERT(typeAliasType != nullptr); typeAliasType->AsETSTypeAliasType()->SetTypeArguments(std::move(typeParamTypes)); if (ok) { AssignTypeParameterConstraints(aliasTypeNode->TypeParams()); @@ -962,7 +972,9 @@ void ETSChecker::CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir: for (auto *prop : annoImpl->Properties()) { auto *field = prop->AsClassProperty(); - auto fieldName = field->Id()->Name(); + auto *id = field->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto fieldName = id->Name(); auto fieldDeclIter = fieldMap.find(fieldName); if (fieldDeclIter == fieldMap.end()) { LogError(diagnostic::AMBIENT_ANNOT_IMPL_OF_UNDEFINED_FIELD, {fieldName, annoDecl->GetBaseName()->Name()}, @@ -1237,7 +1249,9 @@ void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util auto *param = it->AsClassProperty(); auto result = fieldMap.find(param->Id()->Name()); if (result == fieldMap.end()) { - LogError(diagnostic::ANNOT_PROP_UNDEFINED, {param->Id()->Name(), baseName}, param->Start()); + auto *id = param->Id(); + ES2PANDA_ASSERT(id != nullptr); + LogError(diagnostic::ANNOT_PROP_UNDEFINED, {id->Name(), baseName}, param->Start()); continue; } @@ -1312,11 +1326,13 @@ Type *ETSChecker::MaybeBoxInRelation(Type *objectType) Type *ETSChecker::MaybeBoxType(Type *type) const { + ES2PANDA_ASSERT(type != nullptr); return type->IsETSPrimitiveType() ? BoxingConverter::Convert(this, type) : type; } Type *ETSChecker::MaybeUnboxType(Type *type) const { + ES2PANDA_ASSERT(type != nullptr); return type->IsETSUnboxableObject() ? UnboxingConverter::Convert(this, type->AsETSObjectType()) : type; } @@ -1476,6 +1492,7 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::ETSParameterExpression *param, if (!typeAnnotation->IsETSUnionType()) { // #22952: infer optional parameter heuristics auto nonNullishParam = param->IsOptional() ? GetNonNullishType(parameterType) : parameterType; + ES2PANDA_ASSERT(nonNullishParam != nullptr); if (!nonNullishParam->IsETSFunctionType()) { arrowFuncExpr->Check(this); return true; diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 85727571f9..33dac5f76d 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -79,7 +79,9 @@ ETSStringType *ETSChecker::CreateETSStringLiteralType(util::StringView value) ETSResizableArrayType *ETSChecker::CreateETSMultiDimResizableArrayType(Type *element, size_t dimSize) { - ETSResizableArrayType *const arrayType = GlobalBuiltinETSResizableArrayType()->AsETSResizableArrayType(); + ETSObjectType *type = GlobalBuiltinETSResizableArrayType(); + ES2PANDA_ASSERT(type != nullptr); + ETSResizableArrayType *const arrayType = type->AsETSResizableArrayType(); ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); Type *baseArrayType = element; @@ -95,7 +97,9 @@ ETSResizableArrayType *ETSChecker::CreateETSMultiDimResizableArrayType(Type *ele ETSResizableArrayType *ETSChecker::CreateETSResizableArrayType(Type *element) { - ETSResizableArrayType *arrayType = GlobalBuiltinETSResizableArrayType()->AsETSResizableArrayType(); + ETSObjectType *type = GlobalBuiltinETSResizableArrayType(); + ES2PANDA_ASSERT(type != nullptr); + ETSResizableArrayType *arrayType = type->AsETSResizableArrayType(); ES2PANDA_ASSERT(arrayType->TypeArguments().size() == 1U); auto substitution = Substitution {}; @@ -113,6 +117,7 @@ ETSArrayType *ETSChecker::CreateETSArrayType(Type *elementType, bool isCachePoll auto *arrayType = ProgramAllocator()->New(elementType); + ES2PANDA_ASSERT(arrayType != nullptr); std::stringstream ss; arrayType->ToAssemblerTypeWithRank(ss); // arrayType->SetAssemblerName(util::UString(ss.str(), ProgramAllocator()).View()); @@ -218,6 +223,7 @@ Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir } auto signature = ProgramAllocator()->New(info, returnType, func); auto convertedFlag = ConvertToSignatureFlags(func->Modifiers(), func->Flags()); + ES2PANDA_ASSERT(signature != nullptr); func->HasReceiver() ? signature->AddSignatureFlag(SignatureFlags::EXTENSION_FUNCTION | convertedFlag) : signature->AddSignatureFlag(convertedFlag); return signature; @@ -381,6 +387,7 @@ std::tuple ETSChecker::CreateBuiltinArraySign arrayType->ToAssemblerTypeWithRank(ss); auto *info = CreateSignatureInfo(); + ES2PANDA_ASSERT(info != nullptr); info->minArgCount = dim; for (size_t i = 0; i < dim; i++) { @@ -413,6 +420,7 @@ Signature *ETSChecker::CreateBuiltinArraySignature(const ETSArrayType *arrayType auto [internalName, info] = CreateBuiltinArraySignatureInfo(arrayType, dim); auto *signature = CreateSignature(info, GlobalVoidType(), ir::ScriptFunctionFlags::NONE, false); + ES2PANDA_ASSERT(signature != nullptr); signature->SetInternalName(internalName); globalArraySignatures.insert({arrayType, signature}); @@ -425,6 +433,7 @@ ETSObjectType *ETSChecker::CreatePromiseOf(Type *type) ES2PANDA_ASSERT(promiseType->TypeArguments().size() == 1U); auto substitution = Substitution {}; + ES2PANDA_ASSERT(promiseType != nullptr); EmplaceSubstituted(&substitution, promiseType->TypeArguments()[0]->AsETSTypeParameter()->GetOriginal(), type); return promiseType->Substitute(Relation(), &substitution); diff --git a/ets2panda/checker/ets/typeRelationContext.cpp b/ets2panda/checker/ets/typeRelationContext.cpp index eb79912ef8..855ea81830 100644 --- a/ets2panda/checker/ets/typeRelationContext.cpp +++ b/ets2panda/checker/ets/typeRelationContext.cpp @@ -73,6 +73,7 @@ void InstantiationContext::InstantiateType(ETSObjectType *type, ir::TSTypeParame if (typeArgs != nullptr) { for (auto *const it : typeArgs->Params()) { auto *paramType = it->GetType(checker_); + ES2PANDA_ASSERT(paramType != nullptr); if (paramType->IsTypeError()) { result_ = paramType; return; diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 3206fddace..0224e9882e 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -238,8 +238,10 @@ Type *ETSChecker::HandlePartialInterface(ir::TSInterfaceDeclaration *interfaceDe ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefinition *const accessor, ir::ClassDefinition *const newClassDefinition) { + auto *id = accessor->Id(); + ES2PANDA_ASSERT(id != nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *ident = accessor->Id()->Clone(ProgramAllocator(), nullptr); + auto *ident = id->Clone(ProgramAllocator(), nullptr); auto modifierFlag = accessor->Function()->IsGetter() && accessor->Overloads().empty() ? ir::ModifierFlags::READONLY : ir::ModifierFlags::NONE; @@ -375,6 +377,7 @@ ir::TSTypeParameterDeclaration *ETSChecker::ProcessTypeParamAndGenSubstitution( CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->DefaultType(), ProgramAllocator()), ProgramAllocator()); newTypeParams->AddParam(newTypeParam); newTypeParam->SetParent(newTypeParams); + ES2PANDA_ASSERT(likeSubstitution != nullptr); (*likeSubstitution)[classOrInterfaceDefTypeParam] = newTypeParam; } return newTypeParams; @@ -407,6 +410,7 @@ ir::TSTypeParameterInstantiation *ETSChecker::CreateNewSuperPartialRefTypeParams // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ProgramAllocNode(it->second->Name()->Clone(ProgramAllocator(), nullptr), ProgramAllocator()); + ES2PANDA_ASSERT(typeParamRefPart != nullptr); typeParamRefPart->Name()->SetParent(typeParamRefPart); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *typeParamRef = ProgramAllocNode(typeParamRefPart, ProgramAllocator()); @@ -435,6 +439,7 @@ ir::ETSTypeReference *ETSChecker::BuildSuperPartialTypeReference( // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ProgramAllocNode(clonedId, superPartialRefTypeParams, nullptr, ProgramAllocator()); + ES2PANDA_ASSERT(superPartialRefPart != nullptr); superPartialRefPart->Name()->SetParent(superPartialRefPart); if (superPartialRefTypeParams != nullptr) { superPartialRefTypeParams->SetParent(superPartialRefPart); @@ -490,9 +495,9 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla // Put the new property into the class declaration newClassDefinition->EmplaceBody(newProp); } - - if (prop->IsMethodDefinition() && (prop->AsMethodDefinition()->Function()->IsGetter() || - prop->AsMethodDefinition()->Function()->IsSetter())) { + if (prop->IsMethodDefinition() && prop->AsMethodDefinition()->Function() != nullptr && + (prop->AsMethodDefinition()->Function()->IsGetter() || + prop->AsMethodDefinition()->Function()->IsSetter())) { auto *method = prop->AsMethodDefinition(); if (newClassDefinition->Scope()->FindLocal(method->Id()->Name(), varbinder::ResolveBindingOptions::VARIABLES) != nullptr) { @@ -520,6 +525,7 @@ ir::MethodDefinition *ETSChecker::CreateNullishAccessor(ir::MethodDefinition *co const auto interfaceCtx = varbinder::LexicalScope::Enter(VarBinder(), interface->Scope()); auto *paramScope = ProgramAllocator()->New(ProgramAllocator(), interface->Scope()); auto *functionScope = ProgramAllocator()->New(ProgramAllocator(), paramScope); + ES2PANDA_ASSERT(functionScope != nullptr); functionScope->BindParamScope(paramScope); paramScope->BindFunctionScope(functionScope); @@ -598,6 +604,7 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na auto *const interfaceId = ProgramAllocNode(name, ProgramAllocator()); const auto [decl, var] = VarBinder()->NewVarDecl(interfaceId->Start(), ProgramAllocator(), interfaceId->Name()); + ES2PANDA_ASSERT(interfaceId != nullptr); interfaceId->SetVariable(var); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -667,9 +674,11 @@ void ETSChecker::CreatePartialTypeInterfaceMethods(ir::TSInterfaceDeclaration *c } auto *const method = prop->AsMethodDefinition(); - ES2PANDA_ASSERT((method->Function()->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); + auto *func = method->Function(); + ES2PANDA_ASSERT(func != nullptr); + ES2PANDA_ASSERT((func->Flags() & ir::ScriptFunctionFlags::OVERLOAD) == 0U); - if (method->Function()->IsGetter() || method->Function()->IsSetter()) { + if (func->IsGetter() || func->IsSetter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) addNullishAccessor(CreateNullishAccessor(method, partialInterface)); } @@ -705,7 +714,9 @@ Type *ETSChecker::CreatePartialTypeInterfaceDecl(ir::TSInterfaceDeclaration *con auto methodscope = partialInterface->Scope()->AsClassScope()->InstanceMethodScope(); // Add getter methods to instancemethodscope. for (auto *const prop : partialInterface->Body()->Body()) { - if (prop->IsMethodDefinition() && prop->AsMethodDefinition()->Function()->IsGetter()) { + auto *func = prop->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + if (prop->IsMethodDefinition() && func->IsGetter()) { auto *decl = ProgramAllocator()->New( ProgramAllocator(), prop->AsMethodDefinition()->Key()->AsIdentifier()->Name(), prop); methodscope->AddDecl(ProgramAllocator(), decl, ScriptExtension::ETS); @@ -790,6 +801,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par // Create class declaration node // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const classDecl = ProgramAllocNode(classDef, ProgramAllocator()); + ES2PANDA_ASSERT(classDecl != nullptr); classDecl->SetParent(classDeclProgram->Ast()); // Class definition is scope bearer, not class declaration @@ -891,6 +903,7 @@ std::pair ETSChecker::CreateScriptFuncti // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const body = ProgramAllocNode(ProgramAllocator(), std::move(statements)); + ES2PANDA_ASSERT(body != nullptr); body->SetScope(scope); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) id = ProgramAllocNode(util::UString(std::string("constructor"), ProgramAllocator()).View(), @@ -959,7 +972,7 @@ Type *ETSChecker::GetReadonlyType(Type *type) } NamedTypeStackElement ntse(this, type); - + ES2PANDA_ASSERT(type != nullptr); if (type->IsETSArrayType()) { ETSArrayType *const clonedArrayType = ProgramAllocator()->New(type->AsETSArrayType()->ElementType()); @@ -1025,6 +1038,7 @@ Type *ETSChecker::HandleRequiredType(Type *typeToBeRequired) for (auto *type : typeToBeRequired->AsETSUnionType()->ConstituentTypes()) { if (type->IsETSObjectType()) { type = type->Clone(this); + ES2PANDA_ASSERT(type != nullptr); MakePropertiesNonNullish(type->AsETSObjectType()); } @@ -1076,7 +1090,7 @@ void ETSChecker::MakePropertyNonNullish(ETSObjectType *const classType, varbinde auto *const nonNullishPropType = GetNonNullishType(propType); auto *const propCopy = prop->Copy(ProgramAllocator(), prop->Declaration()); - + ES2PANDA_ASSERT(propCopy != nullptr); propCopy->SetTsType(nonNullishPropType); classType->RemoveProperty(prop); classType->AddProperty(propCopy); @@ -1106,7 +1120,12 @@ void ETSChecker::ValidateObjectLiteralForRequiredType(const ETSObjectType *const if (requiredType->HasObjectFlag(ETSObjectFlags::INTERFACE)) { for (const auto *method : requiredType->GetDeclNode()->AsTSInterfaceDeclaration()->Body()->Body()) { - if (!method->IsMethodDefinition() || !method->AsMethodDefinition()->Function()->IsGetter()) { + if (!method->IsMethodDefinition()) { + continue; + } + auto *func = method->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + if (!func->IsGetter()) { continue; } diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index 95f65a54bb..db1636c4d1 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -201,6 +201,7 @@ void DestructuringContext::HandleAssignmentPattern(ir::AssignmentExpression *ass void ArrayDestructuringContext::ValidateInferredType() { + ES2PANDA_ASSERT(inferredType_ != nullptr); if (!inferredType_->IsArrayType() && !inferredType_->IsUnionType() && (!inferredType_->IsObjectType() || !inferredType_->AsObjectType()->IsTupleType())) { checker_->ThrowTypeError( @@ -328,6 +329,7 @@ Type *ArrayDestructuringContext::CreateTupleTypeForRest(TupleType *tuple) util::StringView memberIndex = util::Helpers::ToStringView(checker_->Allocator(), iterIndex); auto *memberVar = varbinder::Scope::CreateVar(checker_->Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY, nullptr); + ES2PANDA_ASSERT(memberVar != nullptr); memberVar->SetTsType(tupleElementType); elementFlags.push_back(memberFlag); desc->properties.push_back(memberVar); @@ -528,6 +530,7 @@ void ArrayDestructuringContext::Start() void ObjectDestructuringContext::ValidateInferredType() { + ES2PANDA_ASSERT(inferredType_ != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) if (!inferredType_->IsObjectType()) { return; @@ -559,6 +562,7 @@ Type *ObjectDestructuringContext::CreateObjectTypeForRest(ObjectType *objType) varbinder::Scope::CreateVar(checker_->Allocator(), it->Name(), varbinder::VariableFlags::NONE, nullptr); memberVar->SetTsType(it->TsType()); memberVar->AddFlag(it->Flags()); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(memberVar); } } diff --git a/ets2panda/checker/ts/function.cpp b/ets2panda/checker/ts/function.cpp index e4419c3f8c..b572291219 100644 --- a/ets2panda/checker/ts/function.cpp +++ b/ets2panda/checker/ts/function.cpp @@ -54,7 +54,7 @@ Type *TSChecker::HandleFunctionReturn(ir::ScriptFunction *func) if (func->IsArrow() && func->Body()->IsExpression()) { ElaborateElementwise(returnType, func->Body()->AsExpression(), func->Body()->Start()); } - + ES2PANDA_ASSERT(returnType != nullptr); if (returnType->IsNeverType()) { ThrowTypeError("A function returning 'never' cannot have a reachable end point.", func->ReturnTypeAnnotation()->Start()); @@ -156,6 +156,7 @@ Type *TSChecker::CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpressio util::StringView memberIndex = util::Helpers::ToStringView(Allocator(), index); varbinder::LocalVariable *newMember = varbinder::Scope::CreateVar( Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY | varbinder::VariableFlags::OPTIONAL, nullptr); + ES2PANDA_ASSERT(newMember != nullptr); newMember->SetTsType(GlobalAnyType()); newTuple->AddProperty(newMember); } @@ -193,6 +194,7 @@ Type *TSChecker::CreateParameterTypeForObjectAssignmentPattern(ir::ObjectExpress varbinder::LocalVariable *newProp = varbinder::Scope::CreateVar( Allocator(), prop->Key()->AsIdentifier()->Name(), varbinder::VariableFlags::PROPERTY | varbinder::VariableFlags::OPTIONAL, nullptr); + ES2PANDA_ASSERT(newProp != nullptr); newProp->SetTsType(GetBaseTypeOfLiteralType(CheckTypeCached(assignmentPattern->Right()))); newObject->AddProperty(newProp); } @@ -246,6 +248,7 @@ ReturnedVariable TSChecker::CheckFunctionAssignmentPatternParameter(ir::Assignme util::UString pn(ss.str(), Allocator()); varbinder::LocalVariable *patternVar = varbinder::Scope::CreateVar(Allocator(), pn.View(), varbinder::VariableFlags::NONE, param); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(paramType); patternVar->AddFlag(varbinder::VariableFlags::OPTIONAL); return {patternVar->AsLocalVariable(), nullptr, true}; @@ -264,6 +267,7 @@ std::tuple TSCheck if (typeAnnotation != nullptr) { typeAnnotation->Check(this); restType = typeAnnotation->GetType(this); + ES2PANDA_ASSERT(restType != nullptr); if (!restType->IsArrayType()) { ThrowTypeError("A rest parameter must be of an array type", param->Start()); } @@ -315,6 +319,7 @@ std::tuple TSCheck auto destructuringContext = ArrayDestructuringContext({this, param->AsArrayPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(destructuringContext.InferredType()); return {patternVar->AsLocalVariable(), nullptr, false}; } @@ -337,6 +342,7 @@ std::tuple TSCheck auto destructuringContext = ObjectDestructuringContext( {this, param->AsObjectPattern(), false, false, param->TypeAnnotation(), nullptr}); destructuringContext.Start(); + ES2PANDA_ASSERT(patternVar != nullptr); patternVar->SetTsType(destructuringContext.InferredType()); return {patternVar->AsLocalVariable(), nullptr, false}; } @@ -396,6 +402,7 @@ std::tuple TSCheck void TSChecker::CheckFunctionParameterDeclarations(const ArenaVector ¶ms, SignatureInfo *signatureInfo) { + ES2PANDA_ASSERT(signatureInfo != nullptr); signatureInfo->restVar = nullptr; signatureInfo->minArgCount = 0; @@ -590,6 +597,7 @@ void TSChecker::InferFunctionDeclarationType(const varbinder::FunctionDecl *decl } Signature *overloadSignature = Allocator()->New(overloadSignatureInfo, returnType, func); + ES2PANDA_ASSERT(descWithOverload != nullptr); descWithOverload->callSignatures.push_back(overloadSignature); } diff --git a/ets2panda/checker/ts/helpers.cpp b/ets2panda/checker/ts/helpers.cpp index 9c2455f558..9b5abf6d29 100644 --- a/ets2panda/checker/ts/helpers.cpp +++ b/ets2panda/checker/ts/helpers.cpp @@ -59,7 +59,7 @@ Type *TSChecker::GetBaseTypeOfLiteralType(Type *type) if (HasStatus(CheckerStatus::KEEP_LITERAL_TYPE)) { return type; } - + ES2PANDA_ASSERT(type != nullptr); if (type->IsStringLiteralType()) { return GlobalStringType(); } @@ -382,6 +382,7 @@ void TSChecker::GetTypeParam(varbinder::Variable *var, varbinder::Decl *decl) { ir::AstNode *declaration = FindAncestorUntilGivenType(decl->Node(), ir::AstNodeType::SCRIPT_FUNCTION); + ES2PANDA_ASSERT(declaration != nullptr); if (declaration->IsIdentifier()) { auto *ident = declaration->AsIdentifier(); if (ident->TypeAnnotation() != nullptr) { @@ -499,6 +500,7 @@ Type *TSChecker::GetTypeFromClassOrInterfaceReference([[maybe_unused]] ir::TSTyp if (resolvedType == nullptr) { ObjectDescriptor *desc = Allocator()->New(Allocator()); resolvedType = Allocator()->New(Allocator(), var->Name(), desc); + ES2PANDA_ASSERT(resolvedType != nullptr); resolvedType->SetVariable(var); var->SetTsType(resolvedType); } diff --git a/ets2panda/checker/ts/object.cpp b/ets2panda/checker/ts/object.cpp index d0b36c61dc..bf9d836a98 100644 --- a/ets2panda/checker/ts/object.cpp +++ b/ets2panda/checker/ts/object.cpp @@ -139,6 +139,7 @@ void TSChecker::ResolveUnionTypeMembers(UnionType *type) } } + ES2PANDA_ASSERT(desc != nullptr); desc->callSignatures = callSignatures; desc->constructSignatures = constructSignatures; @@ -333,6 +334,7 @@ varbinder::Variable *TSChecker::GetPropertyOfUnionType(UnionType *type, const ut } varbinder::Variable *syntheticProp = varbinder::Scope::CreateVar(Allocator(), name, flags, nullptr); + ES2PANDA_ASSERT(syntheticProp != nullptr); syntheticProp->SetTsType(CreateUnionType(std::move(collectedTypes))); type->CachedSyntheticProperties().insert({name, syntheticProp}); return syntheticProp; @@ -390,6 +392,7 @@ Type *TSChecker::GetPropertyTypeForIndexType(Type *type, Type *indexType) return type->AsArrayType()->ElementType(); } + ES2PANDA_ASSERT(indexType != nullptr); if (indexType->HasTypeFlag(TypeFlag::STRING_LITERAL | TypeFlag::NUMBER_LITERAL)) { varbinder::Variable *prop = nullptr; @@ -453,6 +456,7 @@ ArenaVector TSChecker::GetBaseTypes(InterfaceType *type) for (auto *extends : declaration->Extends()) { Type *baseType = extends->Expr()->GetType(this); + ES2PANDA_ASSERT(baseType != nullptr); if (!baseType->HasTypeFlag(TypeFlag::OBJECT | TypeFlag::NON_PRIMITIVE | TypeFlag::ANY)) { ThrowTypeError( "An interface can only extend an object type or intersection of object types with statically " diff --git a/ets2panda/checker/ts/typeCreation.cpp b/ets2panda/checker/ts/typeCreation.cpp index c40b8b1ed7..08b9a7ae9b 100644 --- a/ets2panda/checker/ts/typeCreation.cpp +++ b/ets2panda/checker/ts/typeCreation.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -125,6 +125,7 @@ Type *TSChecker::CreateUnionType(ArenaVector &&constituentTypes) Type *TSChecker::CreateObjectTypeWithCallSignature(Signature *callSignature) { auto *objType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(objType != nullptr); objType->AddCallSignature(callSignature); return objType; } @@ -132,6 +133,7 @@ Type *TSChecker::CreateObjectTypeWithCallSignature(Signature *callSignature) Type *TSChecker::CreateObjectTypeWithConstructSignature(Signature *constructSignature) { auto *objType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(objType != nullptr); objType->AddConstructSignature(constructSignature); return objType; } @@ -139,6 +141,7 @@ Type *TSChecker::CreateObjectTypeWithConstructSignature(Signature *constructSign Type *TSChecker::CreateFunctionTypeWithSignature(Signature *callSignature) { auto *funcObjType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(funcObjType != nullptr); funcObjType->AddCallSignature(callSignature); return funcObjType; } @@ -146,6 +149,7 @@ Type *TSChecker::CreateFunctionTypeWithSignature(Signature *callSignature) Type *TSChecker::CreateConstructorTypeWithSignature(Signature *constructSignature) { auto *constructObjType = Allocator()->New(Allocator()->New(Allocator())); + ES2PANDA_ASSERT(constructObjType != nullptr); constructObjType->AddConstructSignature(constructSignature); return constructObjType; } diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index 3c356758c8..c55afdffc6 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -46,9 +46,12 @@ ETSFunctionType::ETSFunctionType(ETSChecker *checker, Signature *signature) extensionFunctionSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), extensionAccessorSigs_(ArenaVector(checker->ProgramAllocator()->Adapter())), name_(""), - assemblerName_(checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) - ->AsETSObjectType() - ->AssemblerName()) + assemblerName_(checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) != + nullptr + ? checker->GlobalBuiltinFunctionType(signature->MinArgCount(), signature->HasRestParameter()) + ->AsETSObjectType() + ->AssemblerName() + : "") { } @@ -56,11 +59,12 @@ ETSFunctionType::ETSFunctionType(ETSChecker *checker, Signature *signature) static void HackThisParameterInExtensionFunctionInvoke(ETSObjectType *interface, size_t arity) { auto invokeName = FunctionalInterfaceInvokeName(arity, false); - auto &callSigsOfInvoke0 = interface->AsETSObjectType() - ->GetOwnProperty(util::StringView(invokeName)) - ->TsType() - ->AsETSFunctionType() - ->CallSignatures(); + auto *property = interface->AsETSObjectType()->GetOwnProperty( + util::StringView(invokeName)); + ES2PANDA_ASSERT(property != nullptr); + auto *tsType = property->TsType(); + ES2PANDA_ASSERT(tsType != nullptr); + auto &callSigsOfInvoke0 = tsType->AsETSFunctionType()->CallSignatures(); for (auto sig : callSigsOfInvoke0) { sig->AddSignatureFlag(SignatureFlags::THIS_RETURN_TYPE); } diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index e7d2fb4229..d6f05582ae 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -238,6 +238,7 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co for (auto &s : signatures) { funcType->AddCallSignature(s); } + ES2PANDA_ASSERT(res != nullptr); res->SetTsType(funcType); funcType->SetVariable(res); @@ -1069,6 +1070,7 @@ varbinder::LocalVariable *ETSObjectType::CopyProperty(varbinder::LocalVariable * if (copiedPropType->Variable() == prop) { copiedPropType->SetVariable(copiedProp); } + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(copiedPropType); return copiedProp; } @@ -1089,6 +1091,7 @@ Type *ETSObjectType::Instantiate(ArenaAllocator *const allocator, TypeRelation * auto *const copiedType = checker->CreateETSObjectType(declNode_, flags_); ES2PANDA_ASSERT(copiedType->internalName_ == internalName_); ES2PANDA_ASSERT(copiedType->name_ == name_); + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->typeFlags_ = typeFlags_; copiedType->RemoveObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); copiedType->SetVariable(variable_); @@ -1136,6 +1139,7 @@ static varbinder::LocalVariable *CopyPropertyWithTypeArguments(varbinder::LocalV if (copiedPropType->Variable() == prop || copiedPropType->Variable() == nullptr) { copiedPropType->SetVariable(copiedProp); } + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(copiedPropType); return copiedProp; } @@ -1186,6 +1190,7 @@ static ArenaSubstitution *ComputeEffectiveSubstitution(TypeRelation *const relat void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObjectType *const copiedType, ArenaVector &&newTypeArgs, ETSObjectType *base) { + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->typeFlags_ = typeFlags_; copiedType->RemoveObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY); copiedType->SetVariable(variable_); diff --git a/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp b/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp index 14b5577976..fc451fd070 100644 --- a/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsPartialTypeParameter.cpp @@ -82,8 +82,13 @@ void ETSPartialTypeParameter::IsSubtypeOf(TypeRelation *relation, Type *target) ETSPartialTypeParameter *ETSPartialTypeParameter::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) { - return allocator->New( - GetUnderlying()->Instantiate(allocator, relation, globalTypes)->AsETSTypeParameter(), checker_); + auto *underlying = GetUnderlying(); + ES2PANDA_ASSERT(underlying != nullptr); + auto *instantiated = underlying->Instantiate(allocator, relation, globalTypes); + ES2PANDA_ASSERT(instantiated != nullptr); + auto *typeParam = instantiated->AsETSTypeParameter(); + ES2PANDA_ASSERT(typeParam != nullptr); + return allocator->New(typeParam, checker_); } Type *ETSPartialTypeParameter::Substitute(TypeRelation *relation, const Substitution *substitution) diff --git a/ets2panda/checker/types/ets/etsTupleType.cpp b/ets2panda/checker/types/ets/etsTupleType.cpp index d0eb6e7034..38930b20a3 100644 --- a/ets2panda/checker/types/ets/etsTupleType.cpp +++ b/ets2panda/checker/types/ets/etsTupleType.cpp @@ -198,6 +198,7 @@ Type *ETSTupleType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[ma { auto *const checker = relation->GetChecker()->AsETSChecker(); auto *const tupleType = allocator->New(checker, GetTupleTypesList()); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->typeFlags_ = typeFlags_; return tupleType; } diff --git a/ets2panda/checker/types/ets/etsTupleType.h b/ets2panda/checker/types/ets/etsTupleType.h index 2a326dedf9..f6a76125a9 100644 --- a/ets2panda/checker/types/ets/etsTupleType.h +++ b/ets2panda/checker/types/ets/etsTupleType.h @@ -28,7 +28,10 @@ public: explicit ETSTupleType(ETSChecker *checker, const ArenaVector &typeList) : Type(checker::TypeFlag::ETS_TUPLE), typeList_(typeList), - wrapperType_(checker->GlobalBuiltinTupleType(typeList_.size())->AsETSObjectType()) + // NOLINTNEXTLINE(readability-implicit-bool-conversion) + wrapperType_(checker->GlobalBuiltinTupleType(typeList_.size()) != nullptr + ? checker->GlobalBuiltinTupleType(typeList_.size())->AsETSObjectType() + : nullptr) { typeFlags_ |= TypeFlag::ETS_TUPLE; } diff --git a/ets2panda/checker/types/ets/etsTypeParameter.cpp b/ets2panda/checker/types/ets/etsTypeParameter.cpp index 518a42441b..ebb370321d 100644 --- a/ets2panda/checker/types/ets/etsTypeParameter.cpp +++ b/ets2panda/checker/types/ets/etsTypeParameter.cpp @@ -127,6 +127,7 @@ Type *ETSTypeParameter::Instantiate([[maybe_unused]] ArenaAllocator *allocator, auto *const checker = relation->GetChecker()->AsETSChecker(); auto *const copiedType = checker->CreateTypeParameter(); + ES2PANDA_ASSERT(copiedType != nullptr); copiedType->AddTypeFlag(TypeFlag::GENERIC); copiedType->SetDeclNode(GetDeclNode()); copiedType->SetDefaultType(GetDefaultType()); diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 34f539ad85..6260a4ac8d 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -65,6 +65,7 @@ bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, E Type *ETSUnionType::ComputeAssemblerLUB(ETSChecker *checker, ETSUnionType *un) { auto *const apparent = checker->GetApparentType(un); + ES2PANDA_ASSERT(apparent != nullptr); if (!apparent->IsETSUnionType()) { return apparent; } @@ -368,6 +369,7 @@ bool ETSUnionType::ExtractType(checker::ETSChecker *checker, checker::Type *sour constituentType = constituentType->AsETSTypeParameter()->GetConstraintType(); } else if (constituentType->HasTypeFlag(checker::TypeFlag::GENERIC)) { constituentType = constituentType->Clone(checker); + ES2PANDA_ASSERT(constituentType != nullptr); constituentType->RemoveTypeFlag(checker::TypeFlag::GENERIC); } diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index aafed581be..a1db9138f6 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -35,7 +35,7 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub auto *allocator = checker->ProgramAllocator(); bool anyChange = false; SignatureInfo *newSigInfo = allocator->New(allocator); - + ES2PANDA_ASSERT(newSigInfo != nullptr); if (!signatureInfo_->typeParams.empty()) { for (auto *tparam : signatureInfo_->typeParams) { auto *newTparam = tparam->Substitute(relation, substitution); @@ -86,6 +86,7 @@ Signature *Signature::Substitute(TypeRelation *relation, const Substitution *sub Signature *Signature::CreateSignatureForSubstitute(ArenaAllocator *allocator, SignatureInfo *sigInfo, Type *returnType) { auto *result = allocator->New(sigInfo, returnType, func_); + ES2PANDA_ASSERT(result != nullptr); result->flags_ = flags_; result->internalName_ = internalName_; result->ownerObj_ = ownerObj_; @@ -128,6 +129,7 @@ Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, Gl } auto *const copiedSignature = allocator->New(copiedInfo, returnType_, func_); + ES2PANDA_ASSERT(copiedSignature != nullptr); copiedSignature->flags_ = flags_; copiedSignature->internalName_ = internalName_; copiedSignature->ownerObj_ = ownerObj_; @@ -287,6 +289,7 @@ Signature *Signature::ToArrowSignature(ETSChecker *checker) { auto *allocator = checker->ProgramAllocator(); auto *sigInfo = allocator->New(signatureInfo_, allocator); + ES2PANDA_ASSERT(sigInfo != nullptr); for (auto param : sigInfo->params) { param->SetTsType(checker->MaybeBoxType(param->TsType())); } diff --git a/ets2panda/checker/types/signature.h b/ets2panda/checker/types/signature.h index 8515f6b0ca..4051395469 100644 --- a/ets2panda/checker/types/signature.h +++ b/ets2panda/checker/types/signature.h @@ -49,6 +49,7 @@ public: if (other->restVar != nullptr) { restVar = other->restVar->Copy(allocator, other->restVar->Declaration()); + ES2PANDA_ASSERT(restVar != nullptr); restVar->SetTsType(other->restVar->TsType()); } } diff --git a/ets2panda/checker/types/ts/interfaceType.cpp b/ets2panda/checker/types/ts/interfaceType.cpp index 724bee9caa..ff846e5d8e 100644 --- a/ets2panda/checker/types/ts/interfaceType.cpp +++ b/ets2panda/checker/types/ts/interfaceType.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -148,6 +148,7 @@ Type *InterfaceType::Instantiate(ArenaAllocator *allocator, TypeRelation *relati Type *newInterfaceType = allocator->New(allocator, name_, copiedDesc); + ES2PANDA_ASSERT(newInterfaceType != nullptr); for (auto *it : bases_) { newInterfaceType->AsObjectType()->AsInterfaceType()->AddBase( it->Instantiate(allocator, relation, globalTypes)->AsObjectType()); diff --git a/ets2panda/checker/types/ts/objectDescriptor.cpp b/ets2panda/checker/types/ts/objectDescriptor.cpp index a418e6815b..6dfe4e610e 100644 --- a/ets2panda/checker/types/ts/objectDescriptor.cpp +++ b/ets2panda/checker/types/ts/objectDescriptor.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -34,10 +34,12 @@ varbinder::LocalVariable *ObjectDescriptor::FindProperty(const util::StringView void ObjectDescriptor::Copy(ArenaAllocator *allocator, ObjectDescriptor *copiedDesc, TypeRelation *relation, GlobalTypesHolder *globalTypes) { + ES2PANDA_ASSERT(copiedDesc != nullptr); // copy by hand for (auto *it : properties) { auto *copiedProp = it->Copy(allocator, it->Declaration()); copiedProp->SetTsType(it->TsType()->Instantiate(allocator, relation, globalTypes)); + ES2PANDA_ASSERT(copiedDesc != nullptr); copiedDesc->properties.push_back(copiedProp); } diff --git a/ets2panda/checker/types/ts/unionType.cpp b/ets2panda/checker/types/ts/unionType.cpp index 8ba291ba7b..fe540ce69e 100644 --- a/ets2panda/checker/types/ts/unionType.cpp +++ b/ets2panda/checker/types/ts/unionType.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -111,6 +111,7 @@ void UnionType::RemoveDuplicatedTypes(TypeRelation *relation, ArenaVectorHasConstituentFlag(TypeFlag::ANY)) { return globalTypesHolder->GlobalAnyType(); } @@ -184,6 +185,7 @@ Type *UnionType::Instantiate(ArenaAllocator *allocator, TypeRelation *relation, Type *newUnionType = allocator->New(allocator, std::move(copiedConstituents)); + ES2PANDA_ASSERT(newUnionType != nullptr); return HandleUnionType(newUnionType->AsUnionType(), globalTypes); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/typeRelation.cpp b/ets2panda/checker/types/typeRelation.cpp index ac28d50150..d6de755722 100644 --- a/ets2panda/checker/types/typeRelation.cpp +++ b/ets2panda/checker/types/typeRelation.cpp @@ -121,6 +121,8 @@ bool TypeRelation::IsAssignableTo(Type *source, Type *target) if (result_ == RelationResult::CACHE_MISS) { // NOTE: we support assigning T to Readonly, but do not support assigning Readonly to T // more details in spec + ES2PANDA_ASSERT(source != nullptr); + ES2PANDA_ASSERT(target != nullptr); if (source->HasTypeFlag(TypeFlag::READONLY) && !target->HasTypeFlag(TypeFlag::READONLY)) { result_ = RelationResult::FALSE; } diff --git a/ets2panda/parser/ASparser.cpp b/ets2panda/parser/ASparser.cpp index 8fc21e2cbb..9c5f9cb7cc 100644 --- a/ets2panda/parser/ASparser.cpp +++ b/ets2panda/parser/ASparser.cpp @@ -95,6 +95,7 @@ ir::Decorator *ASParser::ParseDecorator() auto *expr = ParseLeftHandSideExpression(); auto *decorator = AllocNode(expr); + ES2PANDA_ASSERT(decorator != nullptr); decorator->SetRange({start, expr->End()}); return decorator; } @@ -124,6 +125,7 @@ ir::TSTypeAliasDeclaration *ASParser::ParseTypeAliasDeclaration() const util::StringView &ident = Lexer()->GetToken().Ident(); auto *id = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -343,6 +345,7 @@ std::tuple ASParser::ParsePatternElementToken(E } case lexer::TokenType::LITERAL_IDENT: { returnNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(returnNode != nullptr); returnNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -430,6 +433,7 @@ ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionPar key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -446,6 +450,7 @@ ir::Expression *ASParser::ParsePropertyDefinition([[maybe_unused]] ExpressionPar } auto *property = AllocNode(key, value); + ES2PANDA_ASSERT(property != nullptr); property->SetRange({key->Start(), value->End()}); return property; } @@ -570,6 +575,7 @@ ir::TypeNode *ASParser::ParseParenthesizedOrFunctionType(bool throwError) ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type, TypeAnnotationParsingOptions *options) { auto *typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); type->SetRange(Lexer()->GetToken().Loc()); @@ -584,6 +590,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type } typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); auto *next = AllocNode(typeName, Allocator()); current->SetRange(Lexer()->GetToken().Loc()); @@ -646,6 +653,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throw } auto *typeName = AllocNode(name, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); type->SetRange(Lexer()->GetToken().Loc()); @@ -717,6 +725,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationTokenLeftSquareBracket(ir::TypeNode * util::StringView name = "Array"; auto *typeName = AllocNode(name, Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); ArenaVector params(Allocator()->Adapter()); @@ -768,6 +777,7 @@ bool ASParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression } *returnExpression = AllocNode(*returnExpression); + ES2PANDA_ASSERT(*returnExpression != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -815,6 +825,7 @@ bool ASParser::ParsePotentialGenericFunctionCall(ir::Expression *primaryExpr, ir lexer::SourcePosition endLoc = propertyNode->End(); *returnExpression = AllocNode(*returnExpression, propertyNode, typeParams); + ES2PANDA_ASSERT(returnExpression != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, endLoc}); return false; @@ -846,6 +857,7 @@ ir::Expression *ASParser::ParsePotentialAsExpression(ir::Expression *primaryExpr ir::Identifier *ASParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -866,6 +878,7 @@ bool ASParser::ValidateArrowFunctionRestParameter([[maybe_unused]] ir::SpreadEle return true; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ArenaVector ASParser::ParseInterfaceExtendsClause() { Lexer()->NextToken(); // eat extends keyword @@ -877,6 +890,7 @@ ArenaVector ASParser::ParseInterfaceExtendsClause() const lexer::SourcePosition &heritageStart = Lexer()->GetToken().Start(); lexer::SourcePosition heritageEnd = Lexer()->GetToken().End(); auto *extendsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(extendsName != nullptr); extendsName->SetRange(Lexer()->GetToken().Loc()); auto *extendsClause = AllocNode(extendsName, Allocator()); extendsClause->SetRange(Lexer()->GetToken().Loc()); @@ -943,6 +957,7 @@ ir::TSIndexSignature *ASParser::ParseIndexSignature(const lexer::SourcePosition } auto *key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat key @@ -992,12 +1007,14 @@ std::tuple ASParser::ParseInterfacePropertyKey() case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = Lexer()->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = Lexer()->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1008,6 +1025,7 @@ std::tuple ASParser::ParseInterfacePropertyKey() key = AllocNode(Lexer()->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1103,6 +1121,7 @@ ArenaVector ASParser::ParseClassImplementClause() auto *implementsName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); implementsName->SetRange(Lexer()->GetToken().Loc()); auto *implementsClause = AllocNode(implementsName, Allocator()); + ES2PANDA_ASSERT(implementsClause != nullptr); implementsClause->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1281,6 +1300,7 @@ std::tuple ASParser::ParseComputedClassFieldOrIndexSignature(i } auto id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat param @@ -1346,6 +1366,7 @@ std::tuple ASParser::Pa ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); } else { body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); endLoc = body->End(); } @@ -1358,6 +1379,7 @@ ir::AstNode *ASParser::ParseImportDefaultSpecifier(ArenaVector *s Lexer()->NextToken(); // eat local name auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); @@ -1503,6 +1525,7 @@ ir::Statement *ASParser::ParseConstStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl != nullptr); variableDecl->SetStart(constVarStar); ConsumeSemicolon(variableDecl); @@ -1519,6 +1542,7 @@ ir::AnnotatedExpression *ASParser::ParseVariableDeclaratorKey(VariableParsingFla const util::StringView &identStr = Lexer()->GetToken().Ident(); auto init = AllocNode(identStr, Allocator()); + ES2PANDA_ASSERT(init != nullptr); init->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1592,6 +1616,7 @@ ir::ExportDefaultDeclaration *ASParser::ParseExportDefaultDeclaration(const lexe lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -1666,6 +1691,7 @@ ir::Statement *ASParser::ParseNamedExportDeclaration(const lexer::SourcePosition ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, decl->End()}); return exportDeclaration; @@ -1712,6 +1738,7 @@ ir::Statement *ASParser::ParseImportDeclaration([[maybe_unused]] StatementParsin lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); diff --git a/ets2panda/parser/ETSFormattedParser.cpp b/ets2panda/parser/ETSFormattedParser.cpp index f5bb28b326..328ed93d49 100644 --- a/ets2panda/parser/ETSFormattedParser.cpp +++ b/ets2panda/parser/ETSFormattedParser.cpp @@ -301,6 +301,7 @@ ir::Statement *ETSParser::CreateStatement(std::string_view const sourceCode) } auto *const blockStmt = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockStmt != nullptr); blockStmt->SetRange({startLoc, lexer->GetToken().End()}); for (auto *statement : blockStmt->Statements()) { @@ -378,6 +379,7 @@ ir::AstNode *ETSParser::CreateFormattedClassFieldDefinition(std::string_view sou insertingNodes_.swap(insertingNodes); auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); + ES2PANDA_ASSERT(property != nullptr); if (!property->IsTSInterfaceBody() || property->AsTSInterfaceBody()->Body().empty()) { LogError(diagnostic::INVALID_CLASS_FIELD, {}, Lexer()->GetToken().Start()); ES2PANDA_UNREACHABLE(); @@ -394,6 +396,7 @@ ir::AstNode *ETSParser::CreateFormattedClassMethodDefinition(std::string_view so insertingNodes_.swap(insertingNodes); auto *const property = CreateClassElement(sourceCode, DUMMY_ARRAY, ir::ClassDefinitionModifiers::NONE); + ES2PANDA_ASSERT(property != nullptr); if (!property->IsMethodDefinition()) { LogError(diagnostic::INVALID_CLASS_METHOD, {}, Lexer()->GetToken().Start()); ES2PANDA_UNREACHABLE(); @@ -512,6 +515,7 @@ ir::MethodDefinition *ETSParser::CreateConstructorDefinition(ir::ModifierFlags m Lexer()->NextToken(); auto *const methodDefinition = ParseClassMethodDefinition(memberName, modifiers, true); + ES2PANDA_ASSERT(methodDefinition != nullptr); methodDefinition->SetStart(startLoc); return methodDefinition; diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 7b9c2399d8..b64ecbcdb6 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -182,6 +182,7 @@ ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; } @@ -203,6 +204,7 @@ ir::ETSModule *ETSParser::ParseImportsAndReExportOnly(lexer::SourcePosition star auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; } @@ -306,6 +308,7 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; SourceFile sf {src, extSrc->View().Utf8(), importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; parser::Program *newProg = ParseSource(sf); + ES2PANDA_ASSERT(newProg != nullptr); if (!importData.IsImplicitPackageImported() || newProg->IsPackage()) { AddDirectImportsToDirectExternalSources(directImportsFromMainSource, newProg); // don't insert the separate modules into the programs, when we collect implicit package imports @@ -458,6 +461,7 @@ parser::Program *ETSParser::ParseSource(const SourceFile &sourceFile) { importPathManager_->MarkAsParsed(sourceFile.filePath); auto *program = Allocator()->New(Allocator(), GetProgram()->VarBinder()); + ES2PANDA_ASSERT(program != nullptr); auto esp = ExternalSourceParser(this, program); auto lexer = InitLexer(sourceFile); @@ -558,6 +562,7 @@ ir::ScriptFunction *ETSParser::ParseFunction(ParserStatus newStatus) auto *funcNode = AllocNode( Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(signature), funcFlags, mFlags, GetContext().GetLanguage()}); + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({startLoc, endLoc}); // clang-format on @@ -575,6 +580,7 @@ std::tuple ETSParser::P } ir::BlockStatement *body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); return {true, body, body->End(), false}; } @@ -629,6 +635,7 @@ ir::AstNode *ETSParser::ParseInnerConstructorDeclaration(ir::ModifierFlags membe : AllocNode(constructorToken.Ident(), Allocator()); auto *classMethod = ParseClassMethodDefinition(memberName, memberModifiers, isDefault); + ES2PANDA_ASSERT(classMethod != nullptr); classMethod->SetStart(startLoc); return classMethod; @@ -638,6 +645,7 @@ ir::Identifier *ETSParser::CreateInvokeIdentifier() { util::StringView tokenName = util::StringView {compiler::Signatures::STATIC_INVOKE_METHOD}; auto ident = AllocNode(tokenName, Allocator()); + ES2PANDA_ASSERT(ident != nullptr); ident->SetRange({Lexer()->GetToken().Start(), Lexer()->GetToken().End()}); return ident; } @@ -676,6 +684,7 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert auto parseClassMethod = [&memberModifiers, &startLoc, isDefault, this](ir::Identifier *methodName) { auto *classMethod = ParseClassMethodDefinition(methodName, memberModifiers, isDefault); + ES2PANDA_ASSERT(classMethod != nullptr); classMethod->SetStart(startLoc); return classMethod; }; @@ -708,6 +717,7 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert ArenaVector fieldDeclarations(Allocator()->Adapter()); auto *placeholder = AllocNode(std::move(fieldDeclarations)); + ES2PANDA_ASSERT(placeholder != nullptr); ParseClassFieldDefinition(memberName, memberModifiers, placeholder->BodyPtr(), isDefault); return placeholder; } @@ -804,6 +814,7 @@ ir::TSTypeAliasDeclaration *ETSParser::ParseTypeAliasDeclaration() ir::Identifier *id = ExpectIdentifier(); auto *typeAliasDecl = AllocNode(Allocator(), id); + ES2PANDA_ASSERT(typeAliasDecl != nullptr); if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { auto options = @@ -1019,6 +1030,7 @@ ir::TypeNode *ETSParser::ParseTypeReference(TypeAnnotationParsingOptions *option } auto *typeReference = AllocNode(typeRefPart, Allocator()); + ES2PANDA_ASSERT(typeReference != nullptr); typeReference->SetRange({startPos, Lexer()->GetToken().End()}); return typeReference; } @@ -1056,6 +1068,7 @@ ir::TypeNode *ETSParser::ParseLiteralIdent(TypeAnnotationParsingOptions *options if (Lexer()->TryEatTokenFromKeywordType(lexer::TokenType::KEYW_KEYOF)) { auto keyofOptions = *options | TypeAnnotationParsingOptions::REPORT_ERROR; auto *typeAnnotation = ParseTypeAnnotationNoPreferParam(&keyofOptions); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation = AllocNode(typeAnnotation, Allocator()); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); return typeAnnotation; @@ -1125,6 +1138,7 @@ ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::Modifi auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); + ES2PANDA_ASSERT(result != nullptr); result->AddModifier(modifiers); return result; } @@ -1163,6 +1177,7 @@ ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() ir::Expression *name = ParseQualifiedName(); auto *packageDeclaration = AllocNode(name); + ES2PANDA_ASSERT(packageDeclaration != nullptr); packageDeclaration->SetRange({startLoc, Lexer()->GetToken().End()}); ConsumeSemicolon(packageDeclaration); @@ -1190,6 +1205,7 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVectorSetRange(Lexer()->GetToken().Loc()); auto *const importDeclaration = AllocNode( errorLiteral, util::ImportPathManager::ImportMetadata {}, std::move(specifiers), importKind); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, errorLiteral->End()}); return importDeclaration; } @@ -1205,6 +1221,7 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVector(GetContext().GetProgram()), importFlags); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, importPathStringLiteral->End()}); if (Lexer()->GetToken().Ident().Is("assert")) { LogError(diagnostic::ERROR_ARKTS_NO_IMPORT_ASSERTIONS); @@ -1280,6 +1297,7 @@ ArenaVector ETSParser::ParseImportDeclarations() Lexer()->Rewind(pos); auto *const importDeclDefault = ParseImportPathBuildImport(std::move(defaultSpecifiers), true, startLoc, importKind); + ES2PANDA_ASSERT(importDeclDefault != nullptr); if (!importDeclDefault->IsBrokenStatement()) { util::Helpers::CheckDefaultImport(statements); statements.push_back(importDeclDefault->AsETSImportDeclaration()); @@ -1301,6 +1319,7 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExportForAnonymousConst(ir::Mo ir::Expression *constantExpression = ParseExpression(); auto *exported = AllocNode(compiler::Signatures::EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY, Allocator()); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(Lexer()->GetToken().Loc()); ArenaVector exports(Allocator()->Adapter()); @@ -1311,6 +1330,7 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExportForAnonymousConst(ir::Mo auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); + ES2PANDA_ASSERT(result != nullptr); result->AddModifier(modifiers); ConsumeSemicolon(result); @@ -1329,6 +1349,7 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExport(ir::ModifierFlags modif return nullptr; } auto *exported = AllocNode(token.Ident(), Allocator()); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat exported variable name @@ -1338,6 +1359,7 @@ ir::ExportNamedDeclaration *ETSParser::ParseSingleExport(ir::ModifierFlags modif exports.emplace_back(AllocNode(exported, ParseNamedExport(&token))); auto result = AllocNode(Allocator(), static_cast(nullptr), std::move(exports)); + ES2PANDA_ASSERT(result != nullptr); result->AddModifier(modifiers); ConsumeSemicolon(result); @@ -1378,9 +1400,11 @@ void ETSParser::ParseNamedSpecifiesDefaultImport(ArenaVector(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(imported != nullptr); imported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); auto *specifier = AllocNode(imported); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({imported->Start(), imported->End()}); util::Helpers::CheckDefaultImportedName(*resultDefault, specifier, fileName); @@ -1396,8 +1420,10 @@ bool ETSParser::ParseNamedSpecifiesImport(ArenaVector *re ir::Expression *constantExpression = ParseUnaryOrPrefixUpdateExpression(); auto *exported = AllocNode(compiler::Signatures::EXPORT_DEFAULT_CONSTANT_ANONYMOUSLY, Allocator()); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(Lexer()->GetToken().Loc()); auto *exportedAnonyConst = AllocNode(exported, exported->Clone(Allocator(), nullptr)); + ES2PANDA_ASSERT(exportedAnonyConst != nullptr); exportedAnonyConst->SetConstantExpression(constantExpression); exportedAnonyConst->SetDefault(); resultExportDefault->emplace_back(exportedAnonyConst); @@ -1424,6 +1450,7 @@ bool ETSParser::ParseNamedSpecifiesImport(ArenaVector *re } auto *specifier = AllocNode(imported, local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({imported->Start(), local->End()}); util::Helpers::CheckImportedName(*result, specifier, fileName); @@ -1484,6 +1511,7 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA || Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_FROM) { auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, Lexer()->GetToken().End()}); specifiers->push_back(specifier); return; @@ -1493,6 +1521,7 @@ void ETSParser::ParseNameSpaceSpecifier(ArenaVector *specifiers, local = ParseNamedImport(&Lexer()->GetToken()); auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, Lexer()->GetToken().End()}); specifiers->push_back(specifier); @@ -1506,6 +1535,7 @@ ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector * } auto *imported = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(imported != nullptr); imported->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // Eat import specifier. @@ -1570,6 +1600,7 @@ ir::AnnotatedExpression *ETSParser::GetAnnotatedExpressionFromParam() } auto *const restIdent = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(restIdent != nullptr); restIdent->SetRange(Lexer()->GetToken().Loc()); parameter = AllocNode(ir::AstNodeType::REST_ELEMENT, Allocator(), restIdent); @@ -1688,6 +1719,7 @@ ir::Expression *ETSParser::ParseFunctionParameter() if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; ir::TypeNode *typeAnnotation = ParseTypeAnnotation(&options); + ES2PANDA_ASSERT(typeAnnotation != nullptr); if (typeAnnotation->IsBrokenTypeNode()) { // the compiler can't process "declare class A { static foo(x: {key: string}[]):void; }" correctly // and resolve "{key: string}" as function body, so skip invalid types @@ -1706,12 +1738,14 @@ ir::Expression *ETSParser::ParseFunctionParameter() ir::Expression *ETSParser::CreateParameterThis(ir::TypeNode *typeAnnotation) { auto *paramIdent = AllocNode(varbinder::TypedBinder::MANDATORY_PARAM_THIS, Allocator()); + ES2PANDA_ASSERT(paramIdent != nullptr); paramIdent->SetRange(Lexer()->GetToken().Loc()); typeAnnotation->SetParent(paramIdent); paramIdent->SetTsTypeAnnotation(typeAnnotation); auto *paramExpression = AllocNode(paramIdent, false, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); paramExpression->SetRange({paramIdent->Start(), paramIdent->End()}); return paramExpression; @@ -1720,6 +1754,7 @@ ir::Expression *ETSParser::CreateParameterThis(ir::TypeNode *typeAnnotation) ir::AnnotatedExpression *ETSParser::ParseVariableDeclaratorKey([[maybe_unused]] VariableParsingFlags flags) { ir::Identifier *init = ExpectIdentifier(); + ES2PANDA_ASSERT(init != nullptr); ir::TypeNode *typeAnnotation = nullptr; if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_QUESTION_MARK) { if ((flags & VariableParsingFlags::FOR_OF) != 0U) { @@ -1817,6 +1852,7 @@ void ETSParser::ParseCatchParamTypeAnnotation([[maybe_unused]] ir::AnnotatedExpr if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON)) { TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; if (auto *typeAnnotation = ParseTypeAnnotation(&options); typeAnnotation != nullptr) { + ES2PANDA_ASSERT(param != nullptr); typeAnnotation->SetParent(param); param->SetTsTypeAnnotation(typeAnnotation); } @@ -1875,6 +1911,7 @@ ir::Expression *ETSParser::ParseExpressionOrTypeAnnotation(lexer::TokenType type if (Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_NULL) { auto *typeAnnotation = AllocNode(); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -2022,6 +2059,7 @@ ir::AstNode *ETSParser::ParseAmbientSignature(const lexer::SourcePosition &start auto dummyNode = AllocNode(compiler::Signatures::AMBIENT_INDEXER, indexName, returnType, ir::DummyNodeFlag::INDEXER); + ES2PANDA_ASSERT(dummyNode != nullptr); dummyNode->SetRange({startPos, Lexer()->GetToken().End()}); Lexer()->NextToken(); // eat return type return dummyNode; @@ -2074,7 +2112,9 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati auto *typeParam = AllocNode(paramIdent, constraint, defaultType, varianceModifier, Allocator()); + ES2PANDA_ASSERT(typeParam); + ES2PANDA_ASSERT(typeParam != nullptr); ApplyAnnotationsToNode(typeParam, std::move(annotations), saveLoc); typeParam->SetRange({startLoc, Lexer()->GetToken().End()}); return typeParam; @@ -2249,6 +2289,7 @@ ir::FunctionDeclaration *ETSParser::ParseFunctionDeclaration(bool canBeAnonymous ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::FUNCTION_DECLARATION | ParserStatus::ALLOW_RECEIVER); + ES2PANDA_ASSERT(func != nullptr); if (funcIdentNode != nullptr) { // Error processing. func->SetIdent(funcIdentNode); } @@ -2277,10 +2318,12 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags ParserStatus::EXTENSION_ACCESSOR; ir::Identifier *funcIdentNode = ExpectIdentifier(); + ES2PANDA_ASSERT(funcIdentNode != nullptr); CheckRestrictedBinding(funcIdentNode->Name(), funcIdentNode->Start()); ir::ScriptFunction *func = isGetter ? ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE) : ParseFunction(newStatus); + ES2PANDA_ASSERT(func != nullptr); size_t paramCount = func->Params().size(); size_t getterValidParamCount = 1; size_t setterValidParamCount = 2; diff --git a/ets2panda/parser/ETSparserAnnotations.cpp b/ets2panda/parser/ETSparserAnnotations.cpp index 1f37cf4605..f5f9d5c3a9 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -60,6 +60,7 @@ ir::Expression *ETSParser::ParseAnnotationName() if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD_PERIOD_PERIOD) { Lexer()->Rewind(save); expr = ExpectIdentifier(); + ES2PANDA_ASSERT(expr != nullptr); setAnnotation(expr->AsIdentifier()); return expr; } @@ -67,9 +68,11 @@ ir::Expression *ETSParser::ParseAnnotationName() if (Lexer()->Lookahead() == '.') { auto opt = TypeAnnotationParsingOptions::NO_OPTS; expr = ParseTypeReference(&opt); + ES2PANDA_ASSERT(expr != nullptr); setAnnotation(expr->AsETSTypeReference()->Part()->GetIdent()); } else { expr = ExpectIdentifier(); + ES2PANDA_ASSERT(expr != nullptr); setAnnotation(expr->AsIdentifier()); } @@ -94,6 +97,7 @@ ir::AnnotationDeclaration *ETSParser::ParseAnnotationDeclaration(ir::ModifierFla lexer::SourcePosition endLoc = Lexer()->GetToken().End(); auto *annotationDecl = AllocNode(expr, std::move(properties), Allocator()); + ES2PANDA_ASSERT(annotationDecl != nullptr); annotationDecl->SetRange({startLoc, endLoc}); annotationDecl->AddModifier(flags); return annotationDecl; @@ -133,7 +137,9 @@ ArenaVector ETSParser::ParseAnnotationProperties(ir::ModifierFlag // Probably we can seek for identifier till the enclosing right brace (staring after the next comma?) // if the simplest case failed. auto const pos = Lexer()->Save(); - if (auto *fieldName1 = ExpectIdentifier(); fieldName1->IsErrorPlaceHolder()) { + auto *fieldName1 = ExpectIdentifier(); + ES2PANDA_ASSERT(fieldName1 != nullptr); + if (fieldName1->IsErrorPlaceHolder()) { Lexer()->Rewind(pos); } else { fieldName = fieldName1; @@ -216,6 +222,7 @@ ir::AstNode *ETSParser::ParseAnnotationProperty(ir::Identifier *fieldName, ir::M memberModifiers |= ir::ModifierFlags::ABSTRACT; auto *field = AllocNode(fieldName, initializer, typeAnnotation, memberModifiers, Allocator(), false); + ES2PANDA_ASSERT(field != nullptr); field->SetRange({fieldName->Start(), initializer != nullptr ? initializer->End() : endLoc}); return field; } @@ -287,9 +294,12 @@ void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVecto lexer::SourcePosition pos) { switch (node->Type()) { - case ir::AstNodeType::METHOD_DEFINITION: - node->AsMethodDefinition()->Function()->SetAnnotations(std::move(annotations)); + case ir::AstNodeType::METHOD_DEFINITION: { + auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->SetAnnotations(std::move(annotations)); break; + } case ir::AstNodeType::CLASS_DECLARATION: node->AsClassDeclaration()->Definition()->SetAnnotations(std::move(annotations)); break; @@ -357,6 +367,7 @@ void ETSParser::ApplyAnnotationsToSpecificNodeType(ir::AstNode *node, ArenaVecto static lexer::SourcePosition GetExpressionEndLoc(ir::Expression *expr) { + ES2PANDA_ASSERT(expr != nullptr); if (expr->IsIdentifier()) { return expr->AsIdentifier()->End(); } @@ -398,6 +409,7 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() } auto *annotationUsage = AllocNode(expr, std::move(properties)); + ES2PANDA_ASSERT(annotationUsage != nullptr); annotationUsage->AddModifier(flags); annotationUsage->SetRange({startLoc, Lexer()->GetToken().End()}); return annotationUsage; diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 513242b3e4..8807006489 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -514,6 +514,7 @@ void ETSParser::ParseClassFieldDefinition(ir::Identifier *fieldName, ir::Modifie ValidateFieldModifiers(modifiers, optionalField, initializer, start); auto *field = AllocNode(fieldName, initializer, typeAnnotation, modifiers, Allocator(), false); + ES2PANDA_ASSERT(field != nullptr); field->SetDefaultAccessModifier(isDefault); if (optionalField) { field->AddModifier(ir::ModifierFlags::OPTIONAL); @@ -587,8 +588,10 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth } ir::ScriptFunction *func = ParseFunction(newStatus); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(methodName); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); func->AddModifier(modifiers); @@ -609,11 +612,13 @@ ir::MethodDefinition *ETSParser::ParseClassMethod(ClassElementDescriptor *desc, } ir::ScriptFunction *func = ParseFunction(desc->newStatus); + ES2PANDA_ASSERT(func != nullptr); if (propName->IsIdentifier()) { func->SetIdent(propName->AsIdentifier()->Clone(Allocator(), nullptr)); } auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -763,7 +768,9 @@ void *ETSParser::ApplyAnnotationsToClassElement(ir::AstNode *property, ArenaVect for (auto *node : property->AsTSInterfaceBody()->Body()) { ArenaVector cloneAnnotations(Allocator()->Adapter()); for (auto *annotationUsage : annotations) { - cloneAnnotations.push_back(annotationUsage->Clone(Allocator(), node)->AsAnnotationUsage()); + auto cloneAnnotationUsage = annotationUsage->Clone(Allocator(), node); + ES2PANDA_ASSERT(cloneAnnotationUsage != nullptr); + cloneAnnotations.push_back(cloneAnnotationUsage->AsAnnotationUsage()); } ApplyAnnotationsToNode(node, std::move(cloneAnnotations), pos); } @@ -818,6 +825,7 @@ ir::MethodDefinition *ETSParser::ParseClassGetterSetterMethod(const ArenaVector< : ir::MethodDefinitionKind::SET; Lexer()->NextToken(); // eat get/set auto *methodName = ExpectIdentifier(); + ES2PANDA_ASSERT(methodName != nullptr); if (desc.methodKind == ir::MethodDefinitionKind::GET) { methodName->SetAccessor(); } else { @@ -854,16 +862,18 @@ ir::MethodDefinition *ETSParser::ParseInterfaceGetterSetterMethod(const ir::Modi return nullptr; } method->AddModifier(ir::ModifierFlags::PUBLIC); + auto id = method->Id(); + ES2PANDA_ASSERT(id != nullptr); if (methodKind == ir::MethodDefinitionKind::GET) { - method->Id()->SetAccessor(); + id->SetAccessor(); method->Function()->AddFlag(ir::ScriptFunctionFlags::GETTER); } else { - method->Id()->SetMutator(); + id->SetMutator(); method->Function()->AddFlag(ir::ScriptFunctionFlags::SETTER); } method->AddModifier(ir::ModifierFlags::PUBLIC); - method->Function()->SetIdent(method->Id()->Clone(Allocator(), nullptr)); + method->Function()->SetIdent(id->Clone(Allocator(), nullptr)); method->Function()->AddModifier(method->Modifiers()); bool hasReturn = method->Function()->ReturnTypeAnnotation() != nullptr; @@ -893,6 +903,7 @@ ir::TSInterfaceDeclaration *ETSParser::ParseInterfaceBody(ir::Identifier *name, lexer::SourcePosition bodyStart = Lexer()->GetToken().Start(); auto members = ParseTypeLiteralOrInterface(); auto *body = AllocNode(std::move(members)); + ES2PANDA_ASSERT(body != nullptr); body->SetRange({bodyStart, Lexer()->GetToken().End()}); const auto isExternal = IsExternal(); @@ -915,6 +926,7 @@ ir::Statement *ETSParser::ParseInterfaceDeclaration(bool isStatic) auto *id = ExpectIdentifier(false, true); auto *declNode = ParseInterfaceBody(id, isStatic); + ES2PANDA_ASSERT(declNode != nullptr); declNode->SetRange({interfaceStart, Lexer()->GetToken().End()}); return declNode; @@ -971,6 +983,7 @@ ir::ClassDefinition *ETSParser::ParseClassDefinition(ir::ClassDefinitionModifier auto *classDefinition = AllocNode(identNode, typeParamDecl, superTypeParams, std::move(implements), ctor, superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetRange(bodyRange); @@ -1058,6 +1071,7 @@ ir::AstNode *ETSParser::ParseInterfaceField() auto parseClassMethod = [&fieldModifiers, &startLoc, this](ir::Identifier *methodName) { auto *classMethod = ParseClassMethodDefinition(methodName, fieldModifiers, false); + ES2PANDA_ASSERT(classMethod != nullptr); classMethod->SetStart(startLoc); return classMethod; }; @@ -1077,6 +1091,7 @@ ir::AstNode *ETSParser::ParseInterfaceField() auto *typeAnnotation = ParseInterfaceTypeAnnotation(name); auto *field = AllocNode(name, nullptr, typeAnnotation->Clone(Allocator(), nullptr), fieldModifiers, Allocator(), false); + ES2PANDA_ASSERT(field != nullptr); if (optionalField) { field->AddModifier(ir::ModifierFlags::OPTIONAL); } @@ -1127,6 +1142,7 @@ ir::OverloadDeclaration *ETSParser::ParseInterfaceOverload(ir::ModifierFlags mod return overloadDef; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, ir::MethodDefinitionKind methodKind) { ir::Identifier *name = nullptr; @@ -1171,7 +1187,7 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i auto *func = AllocNode( Allocator(), ir::ScriptFunction::ScriptFunctionData {body, std::move(signature), functionContext.Flags(), flags, GetContext().GetLanguage()}); - + ES2PANDA_ASSERT(func != nullptr); if ((flags & ir::ModifierFlags::STATIC) == 0 && body == nullptr) { func->AddModifier(ir::ModifierFlags::ABSTRACT); } @@ -1179,6 +1195,7 @@ ir::MethodDefinition *ETSParser::ParseInterfaceMethod(ir::ModifierFlags flags, i func->SetRange({startLoc, GetEndLoc(body, func, Lexer())}); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); @@ -1262,6 +1279,7 @@ ir::AstNode *ETSParser::ParseTypeLiteralOrInterfaceMember() LogError(diagnostic::READONLY_INTERFACE_METHOD, {}, startLoc); } auto *method = ParseInterfaceMethod(modifiers, ir::MethodDefinitionKind::METHOD); + ES2PANDA_ASSERT(method != nullptr); method->SetStart(startLoc); return method; } @@ -1318,6 +1336,7 @@ bool ETSParser::CheckClassElement(ir::AstNode *property, [[maybe_unused]] ir::Me void ETSParser::CheckPredefinedMethods(ir::ScriptFunction const *function, const lexer::SourcePosition &position) { + ES2PANDA_ASSERT(function != nullptr); auto const name = function->Id()->Name(); auto const checkAsynchronous = [this, function, &name, &position]() -> void { @@ -1378,7 +1397,9 @@ void ETSParser::CreateImplicitConstructor([[maybe_unused]] ir::MethodDefinition auto *methodDef = BuildImplicitConstructor(ir::ClassDefinitionModifiers::SET_CTOR_ID, startLoc); if ((flags & ir::ModifierFlags::DECLARE) != 0) { - methodDef->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + auto func = methodDef->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } properties.push_back(methodDef); } diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index b38077398c..c4f6989c72 100644 --- a/ets2panda/parser/ETSparserEnums.cpp +++ b/ets2panda/parser/ETSparserEnums.cpp @@ -167,6 +167,7 @@ ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, co auto *const enumDeclaration = AllocNode( Allocator(), key, std::move(members), ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}); + ES2PANDA_ASSERT(enumDeclaration != nullptr); if (InAmbientContext()) { enumDeclaration->AddModifier(ir::ModifierFlags::DECLARE); } diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index bff2cbec61..7cd587f214 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -68,6 +68,7 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress } paramExpression = AllocNode(paramIdent->AsIdentifier(), defaultValue, Allocator()); + ES2PANDA_ASSERT(paramExpression != nullptr); std::string value = GetArgumentsSourceView(Lexer(), lexerPos); paramExpression->SetLexerSaved(util::UString(value, Allocator()).View()); @@ -163,6 +164,7 @@ ir::Expression *ETSParser::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFla ir::Expression *argument = ResolveArgumentUnaryExpr(flags); if (operatorType == lexer::TokenType::KEYW_AWAIT) { auto *awaitExpr = AllocNode(argument); + ES2PANDA_ASSERT(awaitExpr != nullptr); awaitExpr->SetRange({start, argument->End()}); return awaitExpr; } @@ -208,6 +210,7 @@ ir::Expression *ETSParser::ParsePropertyDefinition(ExpressionParseFlags flags) ir::Expression *key = ParsePropertyKey(flags); ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); + ES2PANDA_ASSERT(value != nullptr); lexer::SourcePosition end = value->End(); ir::Expression *returnProperty = nullptr; @@ -255,6 +258,7 @@ ir::Expression *ETSParser::ParseDefaultPrimaryExpression(ExpressionParseFlags fl if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_CLASS || IsStructKeyword()) { Lexer()->NextToken(); // eat 'class' and 'struct' auto *classLiteral = AllocNode(potentialType); + ES2PANDA_ASSERT(classLiteral != nullptr); classLiteral->SetRange({startLoc, Lexer()->GetToken().End()}); return classLiteral; } @@ -477,6 +481,7 @@ ir::ArrowFunctionExpression *ETSParser::ParseArrowFunctionExpression() auto newStatus = ParserStatus::ARROW_FUNCTION | ParserStatus::ALLOW_RECEIVER; auto *func = ParseFunction(newStatus); auto *arrowFuncNode = AllocNode(func, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(func->Range()); return arrowFuncNode; } @@ -605,6 +610,7 @@ ir::Expression *ETSParser::ParsePotentialAsExpression(ir::Expression *primaryExp } auto *asExpression = AllocNode(primaryExpr, type, false); + ES2PANDA_ASSERT(asExpression != nullptr); asExpression->SetRange(primaryExpr->Range()); return asExpression; } @@ -672,6 +678,7 @@ ir::Expression *ETSParser::ParseNewExpression() } while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); auto *multiArray = AllocNode(typeReference, std::move(dimensions)); + ES2PANDA_ASSERT(multiArray != nullptr); multiArray->SetRange({start, endLoc}); return multiArray; } @@ -699,6 +706,7 @@ ir::Expression *ETSParser::ParseAsyncExpression() return nullptr; } auto *arrowFuncNode = AllocNode(func, Allocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetRange(func->Range()); return arrowFuncNode; } @@ -709,6 +717,7 @@ ir::Expression *ETSParser::ParseAwaitExpression() Lexer()->NextToken(); ir::Expression *argument = ParseExpression(); auto *awaitExpression = AllocNode(argument); + ES2PANDA_ASSERT(awaitExpression != nullptr); awaitExpression->SetRange({start, Lexer()->GetToken().End()}); return awaitExpression; } @@ -735,6 +744,7 @@ bool ETSParser::ParsePotentialNonNullExpression(ir::Expression **expression, con } const auto nonNullExpr = AllocNode(*expression); + ES2PANDA_ASSERT(nonNullExpr != nullptr); nonNullExpr->SetRange({startLoc, Lexer()->GetToken().End()}); *expression = nonNullExpr; diff --git a/ets2panda/parser/ETSparserJsDocInfo.cpp b/ets2panda/parser/ETSparserJsDocInfo.cpp index 8ddf1be020..e0dbcb2344 100644 --- a/ets2panda/parser/ETSparserJsDocInfo.cpp +++ b/ets2panda/parser/ETSparserJsDocInfo.cpp @@ -237,9 +237,12 @@ void ETSParser::ApplyJsDocInfoToSpecificNodeType(ir::AstNode *node, ArenaVector< } switch (node->Type()) { - case ir::AstNodeType::METHOD_DEFINITION: - node->AsMethodDefinition()->Function()->SetJsDocInformation(std::move(jsDocInformation)); + case ir::AstNodeType::METHOD_DEFINITION: { + auto *func = node->AsMethodDefinition()->Function(); + ES2PANDA_ASSERT(func != nullptr); + func->SetJsDocInformation(std::move(jsDocInformation)); break; + } case ir::AstNodeType::CLASS_DECLARATION: node->AsClassDeclaration()->Definition()->SetJsDocInformation(std::move(jsDocInformation)); break; diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index 72c121d5fc..d3ecaeedf6 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -60,6 +60,7 @@ ir::Statement *ETSParser::ParseNamespace(ir::ModifierFlags flags) } auto start = Lexer()->GetToken().Start(); ir::ETSModule *ns = ParseNamespaceImp(flags); + ES2PANDA_ASSERT(ns != nullptr); ns->SetRange({start, Lexer()->GetToken().Start()}); return ns; } @@ -76,6 +77,7 @@ ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) auto start = Lexer()->GetToken().Start(); child = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, globalProgram_); + ES2PANDA_ASSERT(child != nullptr); child->SetParent(parent); child->SetRange({start, Lexer()->GetToken().Start()}); child->AddModifier(ir::ModifierFlags::EXPORT); diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 7f59b8b0e3..08fea38576 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -193,6 +193,7 @@ ir::Statement *ETSParser::ParseTopLevelDeclStatement(StatementParsingFlags flags switch (token.Type()) { case lexer::TokenType::KEYW_FUNCTION: { result = ParseFunctionDeclaration(false, memberModifiers); + ES2PANDA_ASSERT(result != nullptr); result->SetStart(startLoc); break; } @@ -370,6 +371,7 @@ ir::Statement *ETSParser::ParseTryStatement() ArenaVector> finalizerInsertions(Allocator()->Adapter()); auto *tryStatement = AllocNode(body, std::move(catchClauses), finalizer, finalizerInsertions); + ES2PANDA_ASSERT(tryStatement != nullptr); tryStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(tryStatement); diff --git a/ets2panda/parser/ETSparserTypes.cpp b/ets2panda/parser/ETSparserTypes.cpp index dc590faec0..44e5712193 100644 --- a/ets2panda/parser/ETSparserTypes.cpp +++ b/ets2panda/parser/ETSparserTypes.cpp @@ -99,6 +99,7 @@ ir::TypeNode *ETSParser::ParsePrimitiveType(TypeAnnotationParsingOptions *option } auto *const typeAnnotation = AllocNode(type, Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return typeAnnotation; @@ -121,6 +122,7 @@ ir::TypeNode *ETSParser::ParseUnionType(ir::TypeNode *const firstType) auto const endLoc = types.back()->End(); auto *const unionType = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(unionType != nullptr); unionType->SetRange({firstType->Start(), endLoc}); return unionType; } @@ -180,6 +182,7 @@ ir::TypeNode *ETSParser::ParseWildcardType(TypeAnnotationParsingOptions *options } auto *wildcardType = AllocNode(typeReference, varianceModifier, Allocator()); + ES2PANDA_ASSERT(wildcardType != nullptr); wildcardType->SetRange({varianceStartLoc, typeReference == nullptr ? varianceEndLoc : typeReference->End()}); return wildcardType; @@ -262,6 +265,7 @@ ir::TypeNode *ETSParser::ParseETSTupleType(TypeAnnotationParsingOptions *const o lexer::SourcePosition endLoc; ParseList(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET, lexer::NextTokenFlags::NONE, parseElem, &endLoc, true); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->SetTypeAnnotationsList(std::move(tupleTypeList)); tupleType->SetRange({startLoc, endLoc}); @@ -308,6 +312,7 @@ ir::TypeNode *ETSParser::ParsePotentialFunctionalType(TypeAnnotationParsingOptio return nullptr; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic // Just to reduce the size of ParseTypeAnnotation(...) method std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnotationParsingOptions *options) { @@ -324,18 +329,21 @@ std::pair ETSParser::GetTypeAnnotationFromToken(TypeAnnota switch (tokenType) { case lexer::TokenType::LITERAL_NULL: { auto typeAnnotation = AllocNode(Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return std::make_pair(typeAnnotation, true); } case lexer::TokenType::KEYW_UNDEFINED: { auto typeAnnotation = AllocNode(Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return std::make_pair(typeAnnotation, true); } case lexer::TokenType::LITERAL_STRING: { auto typeAnnotation = AllocNode(Lexer()->GetToken().String(), Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return std::make_pair(typeAnnotation, true); @@ -453,6 +461,7 @@ ir::TypeNode *ETSParser::ParseThisType(TypeAnnotationParsingOptions *options) } auto *const thisType = AllocNode(Allocator()); + ES2PANDA_ASSERT(thisType != nullptr); thisType->SetRange(tokenLoc); return thisType; @@ -586,6 +595,7 @@ ir::TypeNode *ETSParser::ParseMultilineString() Lexer()->ScanTemplateStringEnd(); auto typeAnnotation = AllocNode(multilineStr, Allocator()); + ES2PANDA_ASSERT(typeAnnotation != nullptr); typeAnnotation->SetRange({startPos, Lexer()->GetToken().End()}); Lexer()->NextToken(); diff --git a/ets2panda/parser/TSparser.cpp b/ets2panda/parser/TSparser.cpp index 164f34c170..9d47819baa 100644 --- a/ets2panda/parser/TSparser.cpp +++ b/ets2panda/parser/TSparser.cpp @@ -149,6 +149,7 @@ ir::Decorator *TSParser::ParseDecorator() } auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); expr = @@ -161,6 +162,7 @@ ir::Decorator *TSParser::ParseDecorator() } auto *result = AllocNode(expr); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({start, expr->End()}); return result; @@ -199,6 +201,7 @@ ir::TSTypeAliasDeclaration *TSParser::ParseTypeAliasDeclaration() const util::StringView &ident = Lexer()->GetToken().Ident(); auto *id = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -441,6 +444,7 @@ ir::TypeNode *TSParser::ParseThisType(bool throwError) } auto *returnType = AllocNode(Allocator()); + ES2PANDA_ASSERT(returnType != nullptr); returnType->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -544,6 +548,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() auto *inferType = AllocNode(typeParam, Allocator()); + ES2PANDA_ASSERT(inferType != nullptr); inferType->SetRange({inferStart, Lexer()->GetToken().End()}); return inferType; @@ -638,6 +643,7 @@ ir::TSTupleType *TSParser::ParseTupleType() Lexer()->NextToken(); // eat ']' auto *tupleType = AllocNode(std::move(elements), Allocator()); + ES2PANDA_ASSERT(tupleType != nullptr); tupleType->SetRange({tupleStart, tupleEnd}); return tupleType; } @@ -858,6 +864,7 @@ ir::TSTypePredicate *TSParser::ParseTypePredicate() if (isAsserts && Lexer()->GetToken().KeywordType() != lexer::TokenType::KEYW_IS) { endPos = parameterName->End(); result = AllocNode(parameterName, typeAnnotation, isAsserts, Allocator()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({startPos, endPos}); return result; } @@ -869,7 +876,7 @@ ir::TSTypePredicate *TSParser::ParseTypePredicate() endPos = typeAnnotation->End(); result = AllocNode(parameterName, typeAnnotation, isAsserts, Allocator()); - + ES2PANDA_ASSERT(result != nullptr); result->SetRange({startPos, endPos}); return result; @@ -938,6 +945,7 @@ ir::TSArrayType *TSParser::ParseArrayType(ir::TypeNode *elementType) lexer::SourcePosition startLoc = elementType->Start(); auto *arrayType = AllocNode(elementType, Allocator()); + ES2PANDA_ASSERT(arrayType != nullptr); arrayType->SetRange({startLoc, endLoc}); return arrayType; @@ -976,6 +984,7 @@ ir::TSUnionType *TSParser::ParseUnionType(ir::TypeNode *type, bool restrictExten auto *unionType = AllocNode(std::move(types), Allocator()); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, unionType); + ES2PANDA_ASSERT(unionType != nullptr); unionType->SetVariable(typeVar); unionType->SetRange({startLoc, endLoc}); @@ -1020,6 +1029,7 @@ ir::TSIntersectionType *TSParser::ParseIntersectionType(ir::Expression *type, bo auto *intersectionType = AllocNode(std::move(types), Allocator()); auto *typeVar = varbinder::Scope::CreateVar(Allocator(), "__type", varbinder::VariableFlags::TYPE, intersectionType); + ES2PANDA_ASSERT(intersectionType != nullptr); intersectionType->SetVariable(typeVar); intersectionType->SetRange({startLoc, endLoc}); @@ -1041,6 +1051,7 @@ private: return parser->AllocNode(bigintNode, parser->Allocator()); } auto *numberNode = parser->AllocNode(lexer->GetToken().GetNumber()); + CHECK_NOT_NULL(numberNode); numberNode->SetRange(lexer->GetToken().Loc()); return parser->AllocNode(numberNode, parser->Allocator()); @@ -1136,6 +1147,7 @@ ir::TypeNode *TSParser::ParseBasicType() return typeAnnotation; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnotation, bool throwError) { if (typeAnnotation != nullptr) { @@ -1200,6 +1212,7 @@ ir::TypeNode *TSParser::ParseParenthesizedOrFunctionType(ir::TypeNode *typeAnnot } auto *result = AllocNode(type, Allocator()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange({typeStart, endLoc}); return result; @@ -1466,6 +1479,7 @@ bool TSParser::IsNamedFunctionExpression() ir::Identifier *TSParser::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1508,6 +1522,7 @@ ir::TSSignatureDeclaration *TSParser::ParseSignatureMember(bool isCallSignature) : ir::TSSignatureDeclaration::TSSignatureDeclarationKind::CONSTRUCT_SIGNATURE; auto *signatureMember = AllocNode( kind, ir::FunctionSignature(typeParamDecl, std::move(params), typeAnnotation)); + ES2PANDA_ASSERT(signatureMember != nullptr); signatureMember->SetRange({memberStartLoc, Lexer()->GetToken().End()}); return signatureMember; @@ -1534,6 +1549,7 @@ ir::TSIndexSignature *TSParser::ParseIndexSignature(const lexer::SourcePosition ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT); auto *key = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat key @@ -1581,12 +1597,14 @@ std::tuple TSParser::ParseInterfacePropertyKey() case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = Lexer()->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = Lexer()->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1597,6 +1615,7 @@ std::tuple TSParser::ParseInterfacePropertyKey() key = AllocNode(Lexer()->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key != nullptr); key->SetRange(Lexer()->GetToken().Loc()); break; } @@ -1905,6 +1924,7 @@ ir::MethodDefinition *TSParser::ParseClassMethod(ClassElementDescriptor *desc, ir::ScriptFunction *func = ParseFunction(desc->newStatus); + ES2PANDA_ASSERT(func != nullptr); if (func->IsOverload() && !desc->decorators.empty()) { ThrowSyntaxError("A decorator can only decorate a method implementation, not an overload.", desc->decorators.front()->Start()); @@ -2089,6 +2109,7 @@ std::tuple TSParser::Pa ThrowSyntaxError("An implementation cannot be declared in ambient contexts."); } else { body = ParseBlockStatement(); + ES2PANDA_ASSERT(body != nullptr); endLoc = body->End(); } @@ -2110,6 +2131,7 @@ ir::AstNode *TSParser::ParseImportDefaultSpecifier(ArenaVector *s } auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); diff --git a/ets2panda/parser/context/classPrivateContext.cpp b/ets2panda/parser/context/classPrivateContext.cpp index a902e95455..d191b3b597 100644 --- a/ets2panda/parser/context/classPrivateContext.cpp +++ b/ets2panda/parser/context/classPrivateContext.cpp @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-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 @@ -24,7 +24,9 @@ namespace ark::es2panda::parser { bool ClassPrivateContext::AddElement(const ir::ClassElement *elem) { bool newPropIsStatic = elem->IsStatic(); - util::StringView newPropName = elem->Id()->Name(); + auto id = elem->Id(); + ES2PANDA_ASSERT(id); + util::StringView newPropName = id->Name(); ir::MethodDefinitionKind newPropMethodKind = ir::MethodDefinitionKind::METHOD; if (elem->IsMethodDefinition()) { @@ -61,7 +63,9 @@ bool ClassPrivateContext::AddElement(const ir::ClassElement *elem) bool ClassPrivateContext::FindElement(const ir::Identifier *elem) const { for (const auto *it : elements_) { - if (it->Id()->Name().Compare(elem->Name()) == 0) { + auto id = it->Id(); + ES2PANDA_ASSERT(id); + if (id->Name().Compare(elem->Name()) == 0) { return true; } } diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 67500b59ac..d01314b752 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -114,6 +114,7 @@ ir::YieldExpression *ParserImpl::ParseYieldExpression() } auto *yieldNode = AllocNode(argument, isDelegate); + ES2PANDA_ASSERT(yieldNode); yieldNode->SetRange({startLoc, endLoc}); return yieldNode; @@ -208,6 +209,7 @@ ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION; auto *arrayExpressionNode = AllocNode(nodeType, std::move(elements), Allocator(), trailingComma); + ES2PANDA_ASSERT(arrayExpressionNode); arrayExpressionNode->SetRange({startLoc, endLoc}); if (inPattern) { @@ -321,6 +323,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF lexer_->NextToken(); auto statements = ParseStatementList(); body = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(body); body->SetRange({bodyStart, lexer_->GetToken().End()}); // This check is redundant since we have ParseStatementList() @@ -581,6 +584,7 @@ ir::Expression *ParserImpl::CreateBinaryAssignmentExpression(ir::Expression *ass auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); + ES2PANDA_ASSERT(binaryAssignmentExpression); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -596,6 +600,7 @@ ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpress ir::Expression *consequent = ParseAssignmentExpressionHelper(); ir::Expression *alternate = ParseExpression(); auto *conditionalExpr = AllocNode(lhsExpression, consequent, alternate); + ES2PANDA_ASSERT(conditionalExpr); conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()}); return conditionalExpr; } @@ -709,6 +714,7 @@ ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenTyp auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); + ES2PANDA_ASSERT(binaryAssignmentExpression); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -798,6 +804,7 @@ ir::Expression *ParserImpl::ParseNewExpression() if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { lexer::SourcePosition endLoc = callee->End(); auto *newExprNode = AllocNode(callee, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -823,6 +830,7 @@ ir::Expression *ParserImpl::ParseNewExpression() &endLoc, true); auto *newExprNode = AllocNode(callee, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -851,6 +859,7 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() } auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::NEW_TARGET); + ES2PANDA_ASSERT(metaProperty); metaProperty->SetRange(loc); lexer_->NextToken(); return metaProperty; @@ -863,6 +872,7 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() ir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode); identNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -875,6 +885,7 @@ ir::BooleanLiteral *ParserImpl::ParseBooleanLiteral() lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE); auto *booleanNode = AllocNode(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE); + ES2PANDA_ASSERT(booleanNode); booleanNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -885,6 +896,7 @@ ir::NullLiteral *ParserImpl::ParseNullLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL); auto *nullNode = AllocNode(); + ES2PANDA_ASSERT(nullNode); nullNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -903,6 +915,7 @@ ir::Literal *ParserImpl::ParseNumberLiteral() numberNode = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(numberNode); numberNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -914,6 +927,7 @@ ir::CharLiteral *ParserImpl::ParseCharLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR); auto *charNode = AllocNode(lexer_->GetToken().Utf16()); + ES2PANDA_ASSERT(charNode); charNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -925,6 +939,7 @@ ir::StringLiteral *ParserImpl::ParseStringLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING); auto *stringNode = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(stringNode); stringNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -935,6 +950,7 @@ ir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED); auto *undefinedNode = AllocNode(); + ES2PANDA_ASSERT(undefinedNode); undefinedNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -946,6 +962,7 @@ ir::ThisExpression *ParserImpl::ParseThisExpression() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_THIS); auto *thisExprNode = AllocNode(); + ES2PANDA_ASSERT(thisExprNode); thisExprNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -965,6 +982,7 @@ ir::RegExpLiteral *ParserImpl::ParseRegularExpression() reParser.ParsePattern(); auto *regexpNode = AllocNode(regexp.patternStr, regexp.flags, regexp.flagsStr); + ES2PANDA_ASSERT(regexpNode); regexpNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -976,6 +994,7 @@ ir::SuperExpression *ParserImpl::ParseSuperExpression() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER); auto *superExprNode = AllocNode(); + ES2PANDA_ASSERT(superExprNode); superExprNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); // eat super @@ -1024,6 +1043,7 @@ ir::Expression *ParserImpl::ParseHashMaskOperator() } auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(privateIdent); privateIdent->SetPrivate(true); lexer_->NextToken(); @@ -1045,6 +1065,7 @@ ir::Expression *ParserImpl::ParseClassExpression() } auto *classExpr = AllocNode(classDefinition); + ES2PANDA_ASSERT(classExpr); classExpr->SetRange({startLoc, classDefinition->End()}); return classExpr; @@ -1283,6 +1304,7 @@ void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::E amended->SetParent(nullptr); // Next line overwrite parent auto *binaryExpr = AllocNode(left, amended, operatorType); + ES2PANDA_ASSERT(binaryExpr); binaryExpr->SetRange({left->Start(), amended->End()}); SetAmendedChildExpression(right, binaryExpr); } @@ -1341,6 +1363,7 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const le } const lexer::SourcePosition &endPos = rightExpr->End(); rightExpr = AllocNode(left, rightExpr, operatorType); + ES2PANDA_ASSERT(rightExpr); rightExpr->SetRange({left->Start(), endPos}); } @@ -1406,6 +1429,7 @@ ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool callExpr = AllocNode(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma); } + ES2PANDA_ASSERT(callExpr); callExpr->SetRange({callee->Start(), endLoc}); isOptionalChain = false; @@ -1443,6 +1467,7 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) returnExpression = AllocNode(leftSideExpr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, true); + ES2PANDA_ASSERT(returnExpression); returnExpression->SetRange({leftSideExpr->Start(), identNode->End()}); lexer_->NextToken(); } @@ -1459,6 +1484,7 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) returnExpression = AllocNode(leftSideExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, true); + ES2PANDA_ASSERT(returnExpression); returnExpression->SetRange({leftSideExpr->Start(), endLoc}); lexer_->NextToken(); } @@ -1482,6 +1508,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expre switch (lexer_->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); + ES2PANDA_ASSERT(returnExpression); (*returnExpression)->SetStart(startLoc); break; } @@ -1557,6 +1584,7 @@ ir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr auto *memberExpr = AllocNode(primaryExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional); + ES2PANDA_ASSERT(memberExpr); memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()}); lexer_->NextToken(); return memberExpr; @@ -1570,12 +1598,14 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri ValidatePrivateIdentifier(); auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(privateIdent); privateIdent->SetRange({memberStart, lexer_->GetToken().End()}); privateIdent->SetPrivate(true); lexer_->NextToken(); auto *memberExpr = AllocNode(primaryExpr, privateIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); + ES2PANDA_ASSERT(memberExpr); memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()}); return memberExpr; } @@ -1585,6 +1615,7 @@ ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExp ir::Identifier *ident = ExpectIdentifier(true); auto *memberExpr = AllocNode(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, false, isOptional); + ES2PANDA_ASSERT(memberExpr); memberExpr->SetRange({primaryExpr->Start(), ident->End()}); return memberExpr; @@ -1647,9 +1678,11 @@ ir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *r const lexer::SourcePosition startLoc) { ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); + ES2PANDA_ASSERT(propertyNode); lexer::SourcePosition endLoc = propertyNode->End(); returnExpression = AllocNode(returnExpression, propertyNode, nullptr); + ES2PANDA_ASSERT(returnExpression); returnExpression->SetRange({startLoc, endLoc}); return returnExpression; @@ -1710,6 +1743,7 @@ ir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::Sou lexer::SourcePosition endLoc = expr->End(); auto chain = AllocNode(expr); + ES2PANDA_ASSERT(chain); chain->SetRange({startLoc, endLoc}); if (expr == top) { @@ -1758,6 +1792,7 @@ ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, Exp returnExpression = AllocNode(returnExpression, lexer_->GetToken().Type(), false); + ES2PANDA_ASSERT(returnExpression); returnExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); } @@ -1808,6 +1843,7 @@ ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool ir::Expression *rightNode = ParseExpression(); auto *assignmentExpression = AllocNode( ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(assignmentExpression); assignmentExpression->SetRange({returnNode->Start(), rightNode->End()}); return assignmentExpression; @@ -1914,6 +1950,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta const util::StringView &ident = lexer_->GetToken().Ident(); auto *key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key); key->SetRange(lexer_->GetToken().Loc()); ir::Expression *value = AllocNode(ident, Allocator()); @@ -1940,6 +1977,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta } auto *returnProperty = AllocNode(key, value); + ES2PANDA_ASSERT(returnProperty); returnProperty->SetRange({start, end}); return returnProperty; @@ -2006,6 +2044,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = lexer_->GetToken().Ident(); key = AllocNode(ident, Allocator()); + ES2PANDA_ASSERT(key); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2013,6 +2052,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = lexer_->GetToken().String(); key = AllocNode(string); + ES2PANDA_ASSERT(key); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2023,6 +2063,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) } else { key = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(key); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2093,6 +2134,7 @@ ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyK size_t paramsSize = methodDefinitonNode->Params().size(); auto *value = AllocNode(methodDefinitonNode); + ES2PANDA_ASSERT(value); value->SetRange(methodDefinitonNode->Range()); if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) { @@ -2142,10 +2184,12 @@ ir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionP } ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); + ES2PANDA_ASSERT(value); lexer::SourcePosition end = value->End(); auto *returnProperty = AllocNode(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); + ES2PANDA_ASSERT(returnProperty); returnProperty->SetRange({start, end}); return returnProperty; @@ -2221,6 +2265,7 @@ ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags fla auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION; auto *objectExpression = AllocNode(nodeType, Allocator(), std::move(properties), trailingComma); + ES2PANDA_ASSERT(objectExpression); objectExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -2267,6 +2312,7 @@ ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *star lexer::SourcePosition end = sequence.back()->End(); auto *sequenceNode = AllocNode(std::move(sequence)); + ES2PANDA_ASSERT(sequenceNode); sequenceNode->SetRange({start, end}); return sequenceNode; @@ -2327,6 +2373,7 @@ ir::Expression *ParserImpl::ParseUnaryOrPrefixUpdateExpression(ExpressionParseFl returnExpr = AllocNode(argument, operatorType); } + ES2PANDA_ASSERT(returnExpr); returnExpr->SetRange({start, end}); return returnExpr; @@ -2357,6 +2404,7 @@ ir::Expression *ParserImpl::ParseImportExpression() } auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::IMPORT_META); + ES2PANDA_ASSERT(metaProperty); metaProperty->SetRange({startLoc, endLoc}); lexer_->NextToken(); @@ -2409,6 +2457,7 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat functionNode->SetStart(startLoc); auto *funcExpr = AllocNode(ident, functionNode); + ES2PANDA_ASSERT(funcExpr); funcExpr->SetRange(functionNode->Range()); return funcExpr; diff --git a/ets2panda/parser/expressionTSParser.cpp b/ets2panda/parser/expressionTSParser.cpp index 0820dc473a..fe80a876b9 100644 --- a/ets2panda/parser/expressionTSParser.cpp +++ b/ets2panda/parser/expressionTSParser.cpp @@ -137,6 +137,7 @@ ir::Expression *TSParser::ParsePotentialAsExpression(ir::Expression *expr) lexer::SourcePosition startLoc = expr->Start(); auto *asExpr = AllocNode(expr, typeAnnotation, isConst); + ES2PANDA_ASSERT(asExpr); asExpr->SetRange({startLoc, Lexer()->GetToken().End()}); if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) { @@ -169,6 +170,7 @@ ir::AnnotatedExpression *TSParser::ParsePatternElementGetReturnNode(ExpressionPa } case lexer::TokenType::LITERAL_IDENT: { ir::AnnotatedExpression *returnNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(returnNode); if (returnNode->AsIdentifier()->Decorators().empty()) { returnNode->SetRange(Lexer()->GetToken().Loc()); @@ -340,6 +342,7 @@ ir::Expression *TSParser::ParseModuleReference() Lexer()->NextToken(); // eat ')' } else { result = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(result); result->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -357,6 +360,7 @@ ir::TSTypeReference *TSParser::ParseConstExpression() identRef->SetRange(Lexer()->GetToken().Loc()); auto *typeReference = AllocNode(identRef, nullptr, Allocator()); + ES2PANDA_ASSERT(typeReference); typeReference->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -379,6 +383,7 @@ bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression } *returnExpression = AllocNode(*returnExpression); + ES2PANDA_ASSERT(*returnExpression); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -436,6 +441,8 @@ private: } }; +// NOLINTNEXTLINE(readability-function-size) +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Expression **returnExpression, const lexer::SourcePosition &startLoc) { @@ -444,6 +451,7 @@ ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Express switch (Lexer()->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); + ES2PANDA_ASSERT(*returnExpression); (*returnExpression)->SetStart(startLoc); break; } diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index f483f40008..47b031611b 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -84,6 +84,7 @@ void ParserImpl::ParseProgram(ScriptKind kind) auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); auto *blockStmt = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockStmt); blockStmt->SetRange({startLoc, lexer_->GetToken().End()}); program_->SetAst(blockStmt); @@ -339,6 +340,7 @@ std::tuple ParserImpl::ParseComputedClassFieldOrIndexSignature return {true, false, false}; } +// CC-OFFNXT(huge_method[C++], G.FUN.01-CPP) solid logic ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) { ir::Expression *propName = nullptr; @@ -379,6 +381,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) } else { propName = AllocNode(lexer_->GetToken().GetNumber()); } + ES2PANDA_ASSERT(propName); propName->SetRange(lexer_->GetToken().Loc()); break; @@ -458,6 +461,7 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, ir::ScriptFunction *func = ParseFunction(desc->newStatus); auto *funcExpr = AllocNode(func); + ES2PANDA_ASSERT(funcExpr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -483,6 +487,7 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, const ArenaVector &properties, ir::Expression *propName, ir::TypeNode *typeAnnotation) { + ES2PANDA_ASSERT(propName); lexer::SourcePosition propEnd = propName->End(); ir::ClassElement *property = nullptr; @@ -590,6 +595,7 @@ ir::ClassElement *ParserImpl::ParseClassStaticBlock() auto *funcExpr = AllocNode(func); auto *staticBlock = AllocNode(funcExpr, Allocator()); + ES2PANDA_ASSERT(staticBlock); staticBlock->SetRange({startPos, lexer_->GetToken().End()}); lexer_->NextToken(); // eat '}' @@ -686,6 +692,7 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, ir::ModifierFlags::CONSTRUCTOR, Allocator(), false); + ES2PANDA_ASSERT(ctor); const auto rangeImplicitContstuctor = lexer::SourceRange(startLoc, startLoc); ctor->IterateRecursively( @@ -705,7 +712,9 @@ void ParserImpl::CreateImplicitConstructor(ir::MethodDefinition *&ctor, ctor = BuildImplicitConstructor(modifiers, startLoc); if ((flags & ir::ModifierFlags::DECLARE) != 0) { - ctor->Function()->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); + auto *ctorFunc = ctor->Function(); + ES2PANDA_ASSERT(ctorFunc); + ctorFunc->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } } @@ -791,6 +800,7 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(ir::ClassDefinitionModifie auto *classDefinition = AllocNode(identNode, nullptr, superTypeParams, std::move(implements), ctor, superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); + ES2PANDA_ASSERT(classDefinition); classDefinition->SetInternalName(privateBinding.View()); classDefinition->SetRange(bodyRange); @@ -950,6 +960,7 @@ std::tuple ParserImpl:: } ir::BlockStatement *body = ParseBlockStatement(); + ES2PANDA_ASSERT(body); return {true, body, body->End(), false}; } @@ -1013,6 +1024,7 @@ ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus) functionContext.Flags(), // CC-OFFNXT(G.FMT.02-CPP) project code style {}, // CC-OFFNXT(G.FMT.02-CPP) project code style context_.GetLanguage()}); // CC-OFF(G.FMT.02-CPP) project code style + ES2PANDA_ASSERT(funcNode); funcNode->SetRange({startLoc, endLoc}); @@ -1042,6 +1054,7 @@ ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags) auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT; auto *spreadElementNode = AllocNode(nodeType, Allocator(), argument); + ES2PANDA_ASSERT(spreadElementNode); spreadElementNode->SetRange({startLocation, argument->End()}); return spreadElementNode; } @@ -1287,6 +1300,7 @@ ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, } auto *ident = AllocNode(tokenName, Allocator()); + ES2PANDA_ASSERT(ident); // NOTE: here actual token can be changed! ident->SetRange({tokenStart, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -1462,6 +1476,7 @@ ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourcePosition &p ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourceRange &range) { auto *node = AllocNode(Allocator()); + ES2PANDA_ASSERT(node); node->SetRange(range); return node; } @@ -1474,6 +1489,7 @@ ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourcePosition &pos) ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourceRange &range) { auto node = AllocNode(Allocator()); + ES2PANDA_ASSERT(node); node->SetRange(range); return node; } diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index 1e1256896e..9da4cfb1f6 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -33,7 +33,7 @@ Program::Program(ArenaAllocator *allocator, varbinder::VarBinder *varbinder) : allocator_(allocator), externalSources_(allocator_->Adapter()), directExternalSources_(allocator_->Adapter()), - extension_(varbinder->Extension()), + extension_(varbinder != nullptr ? varbinder->Extension() : ScriptExtension::INVALID), etsnolintCollection_(allocator_->Adapter()), cfg_(allocator_->New(allocator_)), functionScopes_(allocator_->Adapter()), @@ -132,6 +132,7 @@ void Program::SetPackageInfo(const util::StringView &name, util::ModuleKind kind // NOTE(vpukhov): part of ongoing design void Program::MaybeTransformToDeclarationModule() { + ES2PANDA_ASSERT(ast_); if (IsPackage() || ast_->Statements().empty()) { return; } diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index c4ff7e348a..80b5c97c3d 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -230,6 +230,7 @@ ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::LET); + ES2PANDA_ASSERT(variableDecl); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -248,6 +249,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) lexer_->NextToken(); auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -261,6 +263,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) ir::EmptyStatement *ParserImpl::ParseEmptyStatement() { auto *empty = AllocNode(); + ES2PANDA_ASSERT(empty); empty->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return empty; @@ -269,6 +272,7 @@ ir::EmptyStatement *ParserImpl::ParseEmptyStatement() ir::Statement *ParserImpl::ParseDebuggerStatement() { auto *debuggerNode = AllocNode(); + ES2PANDA_ASSERT(debuggerNode); debuggerNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); ConsumeSemicolon(debuggerNode); @@ -288,6 +292,7 @@ ir::Statement *ParserImpl::ParseFunctionStatement(StatementParsingFlags flags) stmts.push_back(funcDecl); auto *localBlockStmt = AllocNode(Allocator(), std::move(stmts)); + ES2PANDA_ASSERT(localBlockStmt); localBlockStmt->SetRange(funcDecl->Range()); return funcDecl; @@ -333,6 +338,7 @@ ir::Statement *ParserImpl::ParseStructDeclaration(ir::ClassDefinitionModifiers m lexer::SourcePosition endLoc = classDefinition->End(); auto *structDecl = AllocNode(classDefinition, Allocator()); + ES2PANDA_ASSERT(structDecl); structDecl->SetRange({startLoc, endLoc}); return structDecl; } @@ -353,6 +359,7 @@ ir::Statement *ParserImpl::ParseClassDeclaration(ir::ClassDefinitionModifiers mo lexer::SourcePosition endLoc = classDefinition->End(); auto *classDecl = AllocNode(classDefinition, Allocator()); + ES2PANDA_ASSERT(classDecl); classDecl->SetRange({startLoc, endLoc}); return classDecl; } @@ -379,6 +386,7 @@ void ParserImpl::ConsumeSemicolon(ir::Statement *statement) auto const &token = lexer_->GetToken(); auto tokenType = token.Type(); if (tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { + ES2PANDA_ASSERT(statement); statement->SetEnd(token.End()); lexer_->NextToken(); return; @@ -434,6 +442,7 @@ bool ParserImpl::ParseDirective(ArenaVector *statements) bool isDirective = exprNode->IsStringLiteral(); auto *exprStatement = AllocNode(exprNode); + ES2PANDA_ASSERT(exprStatement); exprStatement->SetRange(exprNode->Range()); ConsumeSemicolon(exprStatement); @@ -464,6 +473,7 @@ ir::BlockStatement *ParserImpl::ParseBlockStatement() auto statements = ParseStatementList(); auto *blockNode = AllocNode(Allocator(), std::move(statements)); + ES2PANDA_ASSERT(blockNode); blockNode->SetRange({startLoc, lexer_->GetToken().End()}); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); @@ -495,6 +505,7 @@ ir::Statement *ParserImpl::ParseBreakStatement() } auto *breakStatement = AllocNode(); + ES2PANDA_ASSERT(breakStatement); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -570,6 +581,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() identNode->SetRange(lexer_->GetToken().Loc()); auto *continueStatement = AllocNode(identNode); + ES2PANDA_ASSERT(continueStatement); continueStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -618,6 +630,7 @@ ir::Statement *ParserImpl::ParseDoWhileStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); auto *doWhileStatement = AllocNode(body, condition); + ES2PANDA_ASSERT(doWhileStatement); doWhileStatement->SetRange({startLoc, endLoc}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -664,6 +677,7 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou newStatus |= ParserStatus::FUNCTION_DECLARATION; ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE); + ES2PANDA_ASSERT(func); func->SetIdent(identNode); func->SetStart(startLoc); @@ -726,6 +740,7 @@ ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) lexer::SourcePosition endPos = exprNode->End(); auto *exprStatementNode = AllocNode(exprNode); + ES2PANDA_ASSERT(exprStatementNode); exprStatementNode->SetRange({startPos.GetToken().Start(), endPos}); ConsumeSemicolon(exprStatementNode); @@ -856,6 +871,7 @@ std::tuple ir::AstNode *initNode = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ? ParseSequenceExpression(expr) : expr; + ES2PANDA_ASSERT(initNode); if (initNode->IsConditionalExpression()) { ir::ConditionalExpression *condExpr = initNode->AsConditionalExpression(); @@ -1008,6 +1024,7 @@ ir::Statement *ParserImpl::CreateForStatement(ForStatementNodes &&nodes, ForStat } } + ES2PANDA_ASSERT(forStatement); forStatement->SetRange({startLoc, nodes.body->End()}); return forStatement; @@ -1085,6 +1102,7 @@ ir::Statement *ParserImpl::ParseIfStatement() } auto *ifStatement = AllocNode(test, consequent, alternate); + ES2PANDA_ASSERT(ifStatement); ifStatement->SetRange({startLoc, endLoc}); return ifStatement; } @@ -1115,6 +1133,7 @@ ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &po ir::Statement *body = ParseStatement(StatementParsingFlags::LABELLED); auto *labeledStatement = AllocNode(identNode, body); + ES2PANDA_ASSERT(labeledStatement); labeledStatement->SetRange({pos.GetToken().Start(), body->End()}); return labeledStatement; @@ -1154,6 +1173,7 @@ ir::Statement *ParserImpl::ParseReturnStatement() returnStatement = AllocNode(); } + ES2PANDA_ASSERT(returnStatement); returnStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(returnStatement); @@ -1209,6 +1229,7 @@ ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault) } auto *caseNode = AllocNode(testExpr, std::move(consequents)); + ES2PANDA_ASSERT(caseNode); caseNode->SetRange({caseStartLoc, caseEndLoc}); return caseNode; } @@ -1240,6 +1261,7 @@ ir::Statement *ParserImpl::ParseSwitchStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); auto *switchStatement = AllocNode(discriminant, std::move(cases)); + ES2PANDA_ASSERT(switchStatement); switchStatement->SetRange({startLoc, endLoc}); return switchStatement; } @@ -1264,6 +1286,7 @@ ir::Statement *ParserImpl::ParseThrowStatement() lexer::SourcePosition endLoc = expression->End(); auto *throwStatement = AllocNode(expression); + ES2PANDA_ASSERT(throwStatement); throwStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(throwStatement); @@ -1318,6 +1341,7 @@ ir::CatchClause *ParserImpl::ParseCatchClause() lexer::SourcePosition endLoc = catchBlock->End(); auto *catchClause = AllocNode(param, catchBlock); + ES2PANDA_ASSERT(catchClause); catchClause->SetRange({catchStartLoc, endLoc}); return catchClause; @@ -1362,6 +1386,7 @@ ir::Statement *ParserImpl::ParseTryStatement() lexer_->NextToken(); // eat 'finally' keyword finallyClause = ParseBlockStatement(); + ES2PANDA_ASSERT(finallyClause); endLoc = finallyClause->End(); } @@ -1532,6 +1557,7 @@ ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags) lexer::SourcePosition endLoc = declarators.back()->End(); auto *declaration = AllocNode(varKind, Allocator(), std::move(declarators)); + ES2PANDA_ASSERT(declaration); declaration->SetRange({startLoc, endLoc}); return declaration; @@ -1559,6 +1585,7 @@ ir::Statement *ParserImpl::ParseWhileStatement() lexer::SourcePosition endLoc = body->End(); auto *whileStatement = AllocNode(condition, body); + ES2PANDA_ASSERT(whileStatement); whileStatement->SetRange({startLoc, endLoc}); return whileStatement; @@ -1609,6 +1636,7 @@ ir::ExportDefaultDeclaration *ParserImpl::ParseExportDefaultDeclaration(const le ES2PANDA_ASSERT(declNode != nullptr); lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -1632,6 +1660,7 @@ ir::Identifier *ParserImpl::ParseNamedExport(lexer::Token *exportedToken) const util::StringView &exportedString = exportedToken->Ident(); auto *exported = AllocNode(exportedString, Allocator()); + ES2PANDA_ASSERT(exported); exported->SetRange(exportedToken->Loc()); return exported; @@ -1649,9 +1678,11 @@ ir::ExportAllDeclaration *ParserImpl::ParseExportAllDeclaration(const lexer::Sou lexer_->NextToken(); // eat exported name } ir::StringLiteral *source = ParseFromClause(); + ES2PANDA_ASSERT(source); lexer::SourcePosition endLoc = source->End(); auto *exportDeclaration = AllocNode(source, exported); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(exportDeclaration); @@ -1706,6 +1737,7 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: } auto *exportDeclaration = AllocNode(Allocator(), source, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endPos}); ConsumeSemicolon(exportDeclaration); @@ -1760,6 +1792,7 @@ ir::Statement *ParserImpl::ParseNamedExportDeclaration(const lexer::SourcePositi lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -1808,6 +1841,7 @@ void ParserImpl::ParseNameSpaceImport(ArenaVector *specifiers) ir::Identifier *local = ParseNamedImport(&lexer_->GetToken()); auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier); specifier->SetRange({namespaceStart, lexer_->GetToken().End()}); specifiers->push_back(specifier); @@ -1825,6 +1859,7 @@ ir::Identifier *ParserImpl::ParseNamedImport(lexer::Token *importedToken) CheckRestrictedBinding(importedToken->KeywordType()); auto *local = AllocNode(importedToken->Ident(), Allocator()); + ES2PANDA_ASSERT(local); local->SetRange(importedToken->Loc()); return local; @@ -1871,6 +1906,7 @@ ir::AstNode *ParserImpl::ParseImportDefaultSpecifier(ArenaVector lexer_->NextToken(); // eat local name auto *specifier = AllocNode(local); + ES2PANDA_ASSERT(specifier); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); @@ -1903,6 +1939,7 @@ ir::StringLiteral *ParserImpl::ParseFromClause(bool requireFrom) } auto *source = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(source); source->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -1961,6 +1998,7 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); + ES2PANDA_ASSERT(importDeclaration); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); @@ -1976,6 +2014,7 @@ ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourcePosition &pos ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourceRange &range) { auto *broken = AllocNode(true); + ES2PANDA_ASSERT(broken); broken->SetRange(range); return broken; } @@ -1991,6 +2030,7 @@ bool ParserImpl::IsBrokenStatement(ir::Statement *st) ir::Statement *ParserImpl::AllocEmptyStatement() { auto *empty = AllocNode(); + ES2PANDA_ASSERT(empty); empty->SetRange(lexer_->GetToken().Loc()); return empty; } diff --git a/ets2panda/parser/statementTSParser.cpp b/ets2panda/parser/statementTSParser.cpp index 34dce05dc1..2a4840d461 100644 --- a/ets2panda/parser/statementTSParser.cpp +++ b/ets2panda/parser/statementTSParser.cpp @@ -131,6 +131,7 @@ ir::TSImportEqualsDeclaration *TSParser::ParseTsImportEqualsDeclaration(const le } auto *id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(id); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat id name @@ -190,6 +191,7 @@ ir::ExportDefaultDeclaration *TSParser::ParseExportDefaultDeclaration(const lexe lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -265,6 +267,7 @@ ir::Statement *TSParser::ParseNamedExportDeclaration(const lexer::SourcePosition lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); + ES2PANDA_ASSERT(exportDeclaration); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -293,6 +296,7 @@ ir::Statement *TSParser::ParseExportDeclaration(StatementParsingFlags flags) } default: { auto ret = ParseNamedExportDeclaration(startLoc); + ES2PANDA_ASSERT(ret); if (ret->IsBrokenStatement()) { return ret; } @@ -322,6 +326,7 @@ ir::Statement *TSParser::ParseConstStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); + ES2PANDA_ASSERT(variableDecl); variableDecl->SetStart(constVarStar); ConsumeSemicolon(variableDecl); @@ -364,6 +369,7 @@ ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsin source = ParseFromClause(false); } + ES2PANDA_ASSERT(source); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); importDeclaration->SetRange({startLoc, endLoc}); -- Gitee From cae27f7d255870228323875f7d8f1994a6ec57f0 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Sat, 5 Jul 2025 16:09:09 +0800 Subject: [PATCH 035/107] assert bug fixed Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK7C5 Signed-off-by: yp9522 --- ets2panda/checker/ets/object.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 7cfe16d58e..d401886baa 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1706,7 +1706,10 @@ bool ETSChecker::ValidateTupleIndexFromEtsObject(const ETSTupleType *const tuple if (expr->Property() == nullptr || expr->Property()->Variable() == nullptr || expr->Property()->Variable()->Declaration() == nullptr || expr->Property()->Variable()->Declaration()->Node() == nullptr || - expr->Property()->Variable()->Declaration()->Node()->AsClassElement() == nullptr) { + !(expr->Property()->Variable()->Declaration()->Node()->IsMethodDefinition() || + expr->Property()->Variable()->Declaration()->Node()->IsClassProperty() || + expr->Property()->Variable()->Declaration()->Node()->IsClassStaticBlock() || + expr->Property()->Variable()->Declaration()->Node()->IsOverloadDeclaration())) { LogError(diagnostic::TUPLE_INDEX_NONCONST, {}, expr->Start()); return false; } -- Gitee From c0b55dd16b3e18f116706bf7ea20bc5d304471fd Mon Sep 17 00:00:00 2001 From: zengzengran Date: Sat, 5 Jul 2025 17:09:47 +0800 Subject: [PATCH 036/107] Fix crash in function type with receiver Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK7QM Description: Return annotation for function type with receiver is this, which is inferred as global, and tstype is set incorrectly. Lead to a crash during the unbox lowering phase. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/checker/ETSAnalyzer.cpp | 5 ++- .../extensionFunctionType_return_this.ets | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/function_type_with_receiver/extensionFunctionType_return_this.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index c4d2946155..6387f0f13c 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -459,7 +459,10 @@ checker::Type *ETSAnalyzer::Check(ir::ETSFunctionType *node) const checker->CheckFunctionSignatureAnnotations(node->Params(), node->TypeParams(), node->ReturnType()); auto *signatureInfo = checker->ComposeSignatureInfo(node->TypeParams(), node->Params()); - auto *returnType = checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); + auto *returnType = node->IsExtensionFunction() && node->ReturnType()->IsTSThisType() + ? signatureInfo->params.front()->TsType() + : checker->ComposeReturnType(node->ReturnType(), node->IsAsync()); + auto *const signature = checker->CreateSignature(signatureInfo, returnType, node->Flags(), node->IsExtensionFunction()); if (signature == nullptr) { // #23134 diff --git a/ets2panda/test/runtime/ets/function_type_with_receiver/extensionFunctionType_return_this.ets b/ets2panda/test/runtime/ets/function_type_with_receiver/extensionFunctionType_return_this.ets new file mode 100644 index 0000000000..56514ff521 --- /dev/null +++ b/ets2panda/test/runtime/ets/function_type_with_receiver/extensionFunctionType_return_this.ets @@ -0,0 +1,34 @@ +/* + * 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 B { + value: T; + x:T; + constructor(value: T) { + this.value = value; + } +} + +type FBSI = (this: B, x: string|Int) => this; +function apply(bb: B[], ff: FBSI) { + for (let b of bb) { + arktest.assertEQ(b.ff("hello").value, b.value) + arktest.assertEQ(b.ff("hello").x, "hello") + arktest.assertEQ(ff(b, "hello").value, b.value) + arktest.assertEQ(ff(b, "hello").x, "hello") + } +} +let bb: B[] = [new B("aa"), new B(1)] +apply(bb, (this: B, x: string|Int): this => {this.x = x; return this;} ) -- Gitee From bcb0326cd513a3ff7eaeb856b7e032da21dd847c Mon Sep 17 00:00:00 2001 From: fcc Date: Mon, 23 Jun 2025 10:49:26 +0800 Subject: [PATCH 037/107] remove local class feature Local class has been removed from spec. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICGF3Z Signed-off-by: fcc --- ets2panda/BUILD.gn | 1 - ets2panda/CMakeLists.txt | 1 - ets2panda/REVIEWERS | 1 - .../lowering/ets/localClassLowering.cpp | 300 -------- .../lowering/ets/localClassLowering.h | 52 -- ets2panda/compiler/lowering/phase.cpp | 2 - ets2panda/parser/ETSparserStatements.cpp | 15 +- ets2panda/parser/statementParser.cpp | 2 +- .../test/ast/parser/ets/InvalidClasses.ets | 1 + .../ast/parser/ets/InvalidStatements1.ets | 3 +- .../ast/parser/ets/class_variable_empty.ets | 7 +- ...-class-member-access-modifier-private1.ets | 5 +- ...-class-member-access-modifier-private2.ets | 6 +- ...lass-member-access-modifier-protected1.ets | 6 +- ...lass-member-access-modifier-protected2.ets | 7 +- ...l-class-member-access-modifier-public1.ets | 5 +- ...l-class-member-access-modifier-public2.ets | 7 +- .../parser/ets/local_class_already_class.ets | 4 +- .../ets/local_class_already_interface.ets | 3 +- .../ets/local_class_already_variable.ets | 3 +- .../ets/local_class_in_classfunction.ets | 20 +- .../ets/local_interface_already_class.ets | 3 +- .../test/parser/ets/local-class-expected.txt | 481 ------------- ets2panda/test/parser/ets/local-class.ets | 20 - .../ets/localClassIsPermitted-expected.txt | 672 ------------------ .../test/parser/ets/localClassIsPermitted.ets | 22 - .../test/runtime/ets/InterfaceInBlock.ets | 31 - .../ets/lambdaWithLocalClassAccess.ets | 26 - .../test/runtime/ets/lambda_with_default.ets | 25 - .../ets/local-class-capture-boxing.ets | 218 ------ .../ets/local-class-capture-not-boxing.ets | 151 ---- .../ets/local-class-capture-parameter.ets | 39 - .../ets/local-class-in-local-class.ets | 54 -- .../runtime/ets/local-class-mixed-capture.ets | 46 -- .../local-class-modify-captured-parameter.ets | 41 -- .../ets/local-class-standard-example1.ets | 49 -- .../ets/local-class-standard-example2.ets | 82 --- .../ets/local_class_in_classfunction.ets | 64 -- .../runtime/ets/local_class_in_function.ets | 60 -- .../ets/statement_after_local_class.ets | 29 - ets2panda/util/diagnostic/syntax.yaml | 4 +- 41 files changed, 57 insertions(+), 2511 deletions(-) delete mode 100644 ets2panda/compiler/lowering/ets/localClassLowering.cpp delete mode 100644 ets2panda/compiler/lowering/ets/localClassLowering.h delete mode 100644 ets2panda/test/parser/ets/local-class-expected.txt delete mode 100644 ets2panda/test/parser/ets/local-class.ets delete mode 100644 ets2panda/test/parser/ets/localClassIsPermitted-expected.txt delete mode 100644 ets2panda/test/parser/ets/localClassIsPermitted.ets delete mode 100644 ets2panda/test/runtime/ets/InterfaceInBlock.ets delete mode 100644 ets2panda/test/runtime/ets/lambdaWithLocalClassAccess.ets delete mode 100644 ets2panda/test/runtime/ets/lambda_with_default.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-capture-boxing.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-capture-parameter.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-in-local-class.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-mixed-capture.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-standard-example1.ets delete mode 100644 ets2panda/test/runtime/ets/local-class-standard-example2.ets delete mode 100644 ets2panda/test/runtime/ets/local_class_in_classfunction.ets delete mode 100644 ets2panda/test/runtime/ets/local_class_in_function.ets delete mode 100644 ets2panda/test/runtime/ets/statement_after_local_class.ets diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 8b39e7a632..5a5df7e397 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -235,7 +235,6 @@ libes2panda_sources = [ "compiler/lowering/ets/interfacePropertyDeclarations.cpp", "compiler/lowering/ets/lambdaLowering.cpp", "compiler/lowering/ets/lateInitialization.cpp", - "compiler/lowering/ets/localClassLowering.cpp", "compiler/lowering/ets/objectIndexAccess.cpp", "compiler/lowering/ets/objectIterator.cpp", "compiler/lowering/ets/objectLiteralLowering.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 6f31c4e658..73d465ae36 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -293,7 +293,6 @@ set(ES2PANDA_LIB_SRC compiler/lowering/ets/dynamicImport.cpp compiler/lowering/ets/restTupleLowering.cpp compiler/lowering/ets/spreadLowering.cpp - compiler/lowering/ets/localClassLowering.cpp compiler/lowering/ets/objectIndexAccess.cpp compiler/lowering/ets/objectIterator.cpp compiler/lowering/ets/insertOptionalParametersAnnotation.cpp diff --git a/ets2panda/REVIEWERS b/ets2panda/REVIEWERS index 6835ef0e17..8c8a73c98b 100644 --- a/ets2panda/REVIEWERS +++ b/ets2panda/REVIEWERS @@ -66,7 +66,6 @@ /ets2panda/checker/types/ets/wildcardType.* ^vpukhov @gogabr ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/ @akmaevaleksey ^igelhaus ^Prof1983 ^zelentsovdmitry /ets2panda/compiler/lowering/ets/lambdaLowering.cpp ^vpukhov @akmaevaleksey @gogabr ^igelhaus ^Prof1983 -/ets2panda/compiler/lowering/ets/localClassLowering.cpp @gogabr ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/optionalLowering.cpp ^vpukhov @akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/unionLowering.cpp ^vpukhov @akmaevaleksey ^igelhaus ^Prof1983 /ets2panda/compiler/lowering/ets/topLevelStmts/.* ^vpukhov @akmaevaleksey ^igelhaus ^Prof1983 diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.cpp b/ets2panda/compiler/lowering/ets/localClassLowering.cpp deleted file mode 100644 index 5096f8bac4..0000000000 --- a/ets2panda/compiler/lowering/ets/localClassLowering.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2023-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. - */ - -#include "localClassLowering.h" - -#include "checker/ETSchecker.h" -#include "../util.h" - -namespace ark::es2panda::compiler { - -std::string_view LocalClassConstructionPhase::Name() const -{ - return "LocalClassConstructionPhase"; -} - -static ir::ClassProperty *CreateCapturedField(public_lib::Context *ctx, const varbinder::Variable *capturedVar, - varbinder::ClassScope *scope, size_t &idx) -{ - auto *allocator = ctx->Allocator(); - auto *varBinder = ctx->GetChecker()->AsETSChecker()->VarBinder(); - - // Enter the lambda class instance field scope, every property will be bound to the lambda instance itself - auto fieldCtx = varbinder::LexicalScope::Enter(varBinder, scope->InstanceFieldScope()); - - // Create the name for the synthetic property node - util::UString fieldName(util::StringView("field#"), allocator); - fieldName.Append(std::to_string(idx)); - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *fieldIdent = allocator->New(fieldName.View(), allocator); - - // Create the synthetic class property node - auto *field = - allocator->New(fieldIdent, nullptr, nullptr, ir::ModifierFlags::NONE, allocator, false); - fieldIdent->SetParent(field); - - // Add the declaration to the scope, and set the type based on the captured variable's scope - auto [decl, var] = varBinder->NewVarDecl(fieldIdent->Start(), fieldIdent->Name()); - var->SetScope(scope->InstanceFieldScope()); - var->AddFlag(varbinder::VariableFlags::PROPERTY); - var->SetTsType(capturedVar->TsType()); - - fieldIdent->SetVariable(var); - ES2PANDA_ASSERT(field != nullptr); - field->SetTsType(capturedVar->TsType()); - decl->BindNode(field); - return field; -} - -static ir::Statement *CreateCtorFieldInit(public_lib::Context *ctx, util::StringView name, varbinder::Variable *var) -{ - // Create synthetic field initializers for the local class fields - // The node structure is the following: this.field0 = field0, where the left hand side refers to the local - // classes field, and the right hand side is refers to the constructors parameter - // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - auto *allocator = ctx->Allocator(); - - auto *thisExpr = allocator->New(); - auto *fieldAccessExpr = allocator->New(name, allocator); - auto *leftHandSide = util::NodeAllocator::ForceSetParent( - allocator, thisExpr, fieldAccessExpr, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - auto *rightHandSide = allocator->New(name, allocator); - rightHandSide->SetVariable(var); - auto *initializer = util::NodeAllocator::ForceSetParent( - allocator, leftHandSide, rightHandSide, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - initializer->SetTsType(var->TsType()); - return util::NodeAllocator::ForceSetParent(allocator, initializer); -} - -void LocalClassConstructionPhase::CreateClassPropertiesForCapturedVariables( - public_lib::Context *ctx, ir::ClassDefinition *classDef, ArenaSet const &capturedVars, - ArenaMap &variableMap, - ArenaMap &propertyMap) -{ - size_t idx = 0; - ArenaVector properties(ctx->allocator->Adapter()); - for (auto var : capturedVars) { - ES2PANDA_ASSERT(classDef->Scope()->Type() == varbinder::ScopeType::CLASS); - auto *property = - CreateCapturedField(ctx, var, reinterpret_cast(classDef->Scope()), idx); - LOG(DEBUG, ES2PANDA) << " - Creating property (" << property->Id()->Name() - << ") for captured variable: " << var->Name(); - properties.push_back(property); - ES2PANDA_ASSERT(property->Id() != nullptr); - variableMap[var] = property->Id()->Variable(); - propertyMap[var] = property; - idx++; - } - - classDef->AddProperties(std::move(properties)); -} - -ir::ETSParameterExpression *LocalClassConstructionPhase::CreateParam(public_lib::Context *ctx, - varbinder::FunctionParamScope *scope, - util::StringView name, checker::Type *type) -{ - auto *checker = ctx->GetChecker()->AsETSChecker(); - auto newParam = checker->AddParam(name, nullptr); - newParam->SetTsType(type); - newParam->Ident()->SetTsType(type); - auto paramCtx = varbinder::LexicalScope::Enter(checker->VarBinder(), scope, false); - - auto *paramVar = checker->VarBinder()->AddParamDecl(newParam); - paramVar->SetTsType(newParam->TsType()); - newParam->Ident()->SetVariable(paramVar); - return newParam; -} - -void LocalClassConstructionPhase::ModifyConstructorParameters( - public_lib::Context *ctx, ir::ClassDefinition *classDef, ArenaSet const &capturedVars, - ArenaMap &variableMap, - ArenaMap ¶meterMap) - -{ - auto *classType = classDef->TsType()->AsETSObjectType(); - - for (auto *signature : classType->ConstructSignatures()) { - LOG(DEBUG, ES2PANDA) << " - Modifying Constructor: " << signature->InternalName(); - auto constructor = signature->Function(); - auto &sigParams = signature->Params(); - auto ¶meters = constructor->ParamsForUpdate(); - signature->GetSignatureInfo()->minArgCount += capturedVars.size(); - - ES2PANDA_ASSERT(signature == constructor->Signature()); - for (auto var : capturedVars) { - auto *newParam = CreateParam(ctx, constructor->Scope()->ParamScope(), var->Name(), var->TsType()); - newParam->SetParent(constructor); - // NOTE(psiket) : Moving the parameter after the 'this'. Should modify the AddParam - // to be able to insert after the this. - auto ¶mScopeParams = constructor->Scope()->ParamScope()->Params(); - auto thisParamIt = ++paramScopeParams.begin(); - paramScopeParams.insert(thisParamIt, paramScopeParams.back()); - paramScopeParams.pop_back(); - - parameters.insert(parameters.begin(), newParam); - ES2PANDA_ASSERT(newParam->Variable()->Type() == varbinder::VariableType::LOCAL); - sigParams.insert(sigParams.begin(), newParam->Ident()->Variable()->AsLocalVariable()); - parameterMap[var] = newParam->Ident()->Variable()->AsLocalVariable(); - } - reinterpret_cast(ctx->GetChecker()->AsETSChecker()->VarBinder()) - ->BuildFunctionName(constructor); - LOG(DEBUG, ES2PANDA) << " Transformed Constructor: " << signature->InternalName(); - - auto *body = constructor->Body(); - ArenaVector initStatements(ctx->allocator->Adapter()); - for (auto var : capturedVars) { - auto *propertyVar = variableMap[var]; - auto *initStatement = CreateCtorFieldInit(ctx, propertyVar->Name(), propertyVar); - auto *fieldInit = initStatement->AsExpressionStatement()->GetExpression()->AsAssignmentExpression(); - auto *ctorParamVar = parameterMap[var]; - auto *fieldVar = variableMap[var]; - auto *leftHandSide = fieldInit->Left(); - leftHandSide->AsMemberExpression()->SetObjectType(classType); - leftHandSide->AsMemberExpression()->SetPropVar(fieldVar->AsLocalVariable()); - leftHandSide->AsMemberExpression()->SetIgnoreBox(); - leftHandSide->AsMemberExpression()->SetTsType(fieldVar->TsType()); - leftHandSide->AsMemberExpression()->Object()->SetTsType(classType); - fieldInit->Right()->AsIdentifier()->SetVariable(ctorParamVar); - fieldInit->Right()->SetTsType(ctorParamVar->TsType()); - initStatement->SetParent(body); - initStatements.push_back(initStatement); - } - if (body != nullptr && body->IsBlockStatement()) { - auto &statements = body->AsBlockStatement()->StatementsForUpdates(); - statements.insert(statements.begin(), initStatements.begin(), initStatements.end()); - } - } -} - -void LocalClassConstructionPhase::RemapReferencesFromCapturedVariablesToClassProperties( - ir::ClassDefinition *classDef, ArenaMap &variableMap) -{ - auto *classType = classDef->TsType()->AsETSObjectType(); - auto remapCapturedVariables = [&variableMap](ir::AstNode *childNode) { - if (childNode->Type() == ir::AstNodeType::IDENTIFIER) { - LOG(DEBUG, ES2PANDA) << " checking var:" << (void *)childNode; - const auto &mapIt = variableMap.find(childNode->AsIdentifier()->Variable()); - if (mapIt != variableMap.end()) { - LOG(DEBUG, ES2PANDA) << " Remap: " << childNode->AsIdentifier()->Name() - << " (identifier:" << (void *)childNode - << ") variable:" << (void *)childNode->AsIdentifier()->Variable() - << " -> property variable:" << (void *)mapIt->second; - childNode->AsIdentifier()->SetVariable(mapIt->second); - } else { - } - } - }; - - for (auto *it : classDef->Body()) { - if (it->IsMethodDefinition() && !it->AsMethodDefinition()->IsConstructor()) { - LOG(DEBUG, ES2PANDA) << " - Rebinding variable rerferences in: " - << it->AsMethodDefinition()->Id()->Name().Mutf8().c_str(); - ES2PANDA_ASSERT(it->AsMethodDefinition()->Function() != nullptr); - if (it->AsMethodDefinition()->Function()->Body() == nullptr && - it->AsMethodDefinition()->AsyncPairMethod() != nullptr) { - it->AsMethodDefinition()->AsyncPairMethod()->Function()->Body()->IterateRecursively( - remapCapturedVariables); - } else { - it->AsMethodDefinition()->Function()->Body()->IterateRecursively(remapCapturedVariables); - } - } - } - // Since the constructor with zero parameter is not listed in the class_def body the constructors - // processed separately - for (auto *signature : classType->ConstructSignatures()) { - auto *constructor = signature->Function(); - LOG(DEBUG, ES2PANDA) << " - Rebinding variable rerferences in: " << constructor->Id()->Name(); - if (constructor->Body() != nullptr) { - constructor->Body()->IterateRecursively(remapCapturedVariables); - } - } -} - -void LocalClassConstructionPhase::HandleLocalClass( - public_lib::Context *ctx, - ArenaUnorderedMap> &capturedVarsMap, - ir::ClassDefinition *classDef) -{ - LOG(DEBUG, ES2PANDA) << "Altering local class with the captured variables: " << classDef->InternalName(); - auto capturedVars = FindCaptured(ctx->allocator, classDef); - // Map the captured variable to the variable of the class property - ArenaMap variableMap(ctx->allocator->Adapter()); - // Map the captured variable to the class property - ArenaMap propertyMap(ctx->allocator->Adapter()); - // Map the captured variable to the constructor parameter - ArenaMap parameterMap(ctx->allocator->Adapter()); - - CreateClassPropertiesForCapturedVariables(ctx, classDef, capturedVars, variableMap, propertyMap); - ModifyConstructorParameters(ctx, classDef, capturedVars, variableMap, parameterMap); - RemapReferencesFromCapturedVariablesToClassProperties(classDef, variableMap); - capturedVarsMap.emplace(classDef, std::move(capturedVars)); -} - -bool LocalClassConstructionPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program) -{ - checker::ETSChecker *const checker = ctx->GetChecker()->AsETSChecker(); - ArenaUnorderedMap> capturedVarsMap { - ctx->allocator->Adapter()}; - - program->Ast()->IterateRecursivelyPostorder([&](ir::AstNode *ast) { - if (ast->IsClassDefinition() && ast->AsClassDefinition()->IsLocal()) { - HandleLocalClass(ctx, capturedVarsMap, ast->AsClassDefinition()); - } - }); - - // Alter the instantiations - auto handleLocalClassInstantiation = [ctx, &capturedVarsMap](ir::ClassDefinition *classDef, - ir::ETSNewClassInstanceExpression *newExpr) { - LOG(DEBUG, ES2PANDA) << "Instantiating local class: " << classDef->Ident()->Name(); - auto capturedVarsIt = capturedVarsMap.find(classDef); - ES2PANDA_ASSERT(capturedVarsIt != capturedVarsMap.cend()); - auto &capturedVars = capturedVarsIt->second; - for (auto *var : capturedVars) { - LOG(DEBUG, ES2PANDA) << " - Extending constructor argument with captured variable: " << var->Name(); - - auto *param = ctx->AllocNode(var->Name(), ctx->allocator); - param->SetVariable(var); - param->SetIgnoreBox(); - param->SetTsType(param->Variable()->TsType()); - param->SetParent(newExpr); - newExpr->AddToArgumentsFront(param); - } - }; - - program->Ast()->IterateRecursivelyPostorder([&](ir::AstNode *ast) { - if (ast->IsETSNewClassInstanceExpression()) { - auto *newExpr = ast->AsETSNewClassInstanceExpression(); - checker::Type *calleeType = newExpr->GetTypeRef()->Check(checker); - if (calleeType->IsETSAnyType()) { - return; - } - - ES2PANDA_ASSERT(calleeType->IsETSObjectType()); - auto *calleeObj = calleeType->AsETSObjectType(); - if (!calleeObj->GetDeclNode()->IsClassDefinition()) { - return; - } - - auto *classDef = calleeObj->GetDeclNode()->AsClassDefinition(); - if (classDef->IsLocal()) { - handleLocalClassInstantiation(classDef, newExpr); - } - } - }); - - return true; -} - -} // namespace ark::es2panda::compiler diff --git a/ets2panda/compiler/lowering/ets/localClassLowering.h b/ets2panda/compiler/lowering/ets/localClassLowering.h deleted file mode 100644 index 08ee325919..0000000000 --- a/ets2panda/compiler/lowering/ets/localClassLowering.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023-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. - */ - -#ifndef ES2PANDA_COMPILER_LOWERING_LOCAL_CLASS_LOWERING_H -#define ES2PANDA_COMPILER_LOWERING_LOCAL_CLASS_LOWERING_H - -#include "compiler/lowering/phase.h" - -namespace ark::es2panda::compiler { - -class LocalClassConstructionPhase : public PhaseForBodies { -public: - std::string_view Name() const override; - bool PerformForModule(public_lib::Context *ctx, parser::Program *program) override; - -protected: - void CreateClassPropertiesForCapturedVariables(public_lib::Context *ctx, ir::ClassDefinition *classDef, - ArenaSet const &capturedVars, - ArenaMap &variableMap, - ArenaMap &propertyMap); - - void ModifyConstructorParameters(public_lib::Context *ctx, ir::ClassDefinition *classDef, - ArenaSet const &capturedVars, - ArenaMap &variableMap, - ArenaMap ¶meterMap); - - void RemapReferencesFromCapturedVariablesToClassProperties( - ir::ClassDefinition *classDef, ArenaMap &variableMap); - - void HandleLocalClass(public_lib::Context *ctx, - ArenaUnorderedMap> &capturedVarsMap, - ir::ClassDefinition *classDef); - - ir::ETSParameterExpression *CreateParam(public_lib::Context *ctx, varbinder::FunctionParamScope *scope, - util::StringView name, checker::Type *type); -}; - -} // namespace ark::es2panda::compiler - -#endif diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 64904ad59e..6c49ef813b 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -47,7 +47,6 @@ #include "compiler/lowering/ets/interfacePropertyDeclarations.h" #include "compiler/lowering/ets/lambdaLowering.h" #include "compiler/lowering/ets/dynamicImport.h" -#include "compiler/lowering/ets/localClassLowering.h" #include "compiler/lowering/ets/objectIndexAccess.h" #include "compiler/lowering/ets/objectIterator.h" #include "compiler/lowering/ets/objectLiteralLowering.h" @@ -154,7 +153,6 @@ std::vector GetETSPhaseList() new LambdaConversionPhase, new UnionLowering, new ExpandBracketsPhase, - new LocalClassConstructionPhase, new PartialExportClassGen, new InterfaceObjectLiteralLowering, // must be put after all classes are generated. new ObjectLiteralLowering, diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 7f59b8b0e3..608f01b4a2 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -381,9 +381,13 @@ ir::Statement *ETSParser::ParseClassStatement([[maybe_unused]] StatementParsingF ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { modFlags |= ParseClassModifiers(); - return ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | - ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, - modFlags); + const auto &rangeClass = Lexer()->GetToken().Loc(); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"CLASS"}, rangeClass.start); + // Try to parse class and drop the result. + ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | + ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, + modFlags); + return AllocBrokenStatement(rangeClass); } // NOLINTNEXTLINE(google-default-arguments) @@ -391,10 +395,11 @@ ir::Statement *ETSParser::ParseStructStatement([[maybe_unused]] StatementParsing ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { const auto &rangeStruct = Lexer()->GetToken().Loc(); - LogError(diagnostic::ILLEGAL_START_STRUCT, {}, rangeStruct.start); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"STRUCT"}, rangeStruct.start); + // Try to parse struct and drop the result. ParseClassDeclaration(modifiers | ir::ClassDefinitionModifiers::ID_REQUIRED | ir::ClassDefinitionModifiers::CLASS_DECL | ir::ClassDefinitionModifiers::LOCAL, - modFlags); // Try to parse struct and drop the result. + modFlags); return AllocBrokenStatement(rangeStruct); } diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index c4ff7e348a..c3f9acc4f2 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -302,7 +302,7 @@ ir::Statement *ParserImpl::ParsePotentialExpressionStatement(StatementParsingFla ir::Statement *ParserImpl::ParseStructStatement([[maybe_unused]] StatementParsingFlags flags, ir::ClassDefinitionModifiers modifiers, ir::ModifierFlags modFlags) { - LogError(diagnostic::ILLEGAL_START_STRUCT); + LogError(diagnostic::ILLEGAL_START_STRUCT_CLASS, {"STRUCT"}); return ParseStructDeclaration(modifiers, modFlags); } diff --git a/ets2panda/test/ast/parser/ets/InvalidClasses.ets b/ets2panda/test/ast/parser/ets/InvalidClasses.ets index 85d1c1fbf9..b73dc9af4c 100644 --- a/ets2panda/test/ast/parser/ets/InvalidClasses.ets +++ b/ets2panda/test/ast/parser/ets/InvalidClasses.ets @@ -112,6 +112,7 @@ interface I1 { /* @@? 58:25 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ /* @@? 58:25 Error SyntaxError: Unexpected token, expected ',' or ')'. */ /* @@? 58:25 Error SyntaxError: Unexpected token '}'. */ +/* @@? 61:5 Error SyntaxError: Illegal start of CLASS expression. */ /* @@? 62:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ /* @@? 66:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ /* @@? 66:18 Error SyntaxError: Private interface methods must have body. */ diff --git a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets index 0e78be95d1..a0a247f919 100644 --- a/ets2panda/test/ast/parser/ets/InvalidStatements1.ets +++ b/ets2panda/test/ast/parser/ets/InvalidStatements1.ets @@ -65,6 +65,7 @@ throw /* @@? 42:1 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ /* @@? 43:5 Error SyntaxError: Expected '{', got 'let'. */ /* @@? 45:9 Error SyntaxError: Unexpected token '{'. */ +/* @@? 47:1 Error SyntaxError: Illegal start of CLASS expression. */ /* @@? 48:5 Error SyntaxError: Unexpected token 'let'. */ /* @@? 52:1 Error SyntaxError: Illegal newline after throw. */ -/* @@? 71:1 Error SyntaxError: Expected '}', got 'end of stream'. */ +/* @@? 72:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/class_variable_empty.ets b/ets2panda/test/ast/parser/ets/class_variable_empty.ets index 659ee129ea..cb91389b8d 100644 --- a/ets2panda/test/ast/parser/ets/class_variable_empty.ets +++ b/ets2panda/test/ast/parser/ets/class_variable_empty.ets @@ -19,6 +19,9 @@ function main(): void { let a: A = new A; arktest.assertTrue(a != null) } - arktest.assertTrue(/* @@ label */a != null) + arktest.assertTrue(a != null) } -/* @@@ label Error TypeError: Unresolved reference a */ \ No newline at end of file +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 19:12 Error TypeError: Cannot find type 'A'. */ +/* @@? 19:20 Error TypeError: Cannot find type 'A'. */ +/* @@? 22:22 Error TypeError: Unresolved reference a */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets index 43fd173a70..2e523713b2 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private1.ets @@ -17,7 +17,8 @@ function foo() { class LocalClass { - /* @@ label */private property : int; + private property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets index 00c1422a83..85dd9b2df4 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-private2.ets @@ -17,8 +17,8 @@ function foo() { class LocalClass { - /* @@ label */private method() : void; + private method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:37 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets index 4091ddc869..2e7a15b760 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected1.ets @@ -17,7 +17,9 @@ function foo() { class LocalClass { - /* @@ label */protected property : int; + protected property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets index 3d9cee80d4..a320b25eb8 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-protected2.ets @@ -17,8 +17,9 @@ function foo() { class LocalClass { - /* @@ label */protected method() : void; + protected method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:39 Error TypeError: Only abstract or native methods can't have body. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets index 815ca264d0..3b55135eb7 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public1.ets @@ -17,7 +17,8 @@ function foo() { class LocalClass { - /* @@ label */public property : int; + public property : int; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets index d04ccf89ed..5bf531cf9f 100644 --- a/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets +++ b/ets2panda/test/ast/parser/ets/local-class-member-access-modifier-public2.ets @@ -17,8 +17,9 @@ function foo() { class LocalClass { - /* @@ label */public method() : void; + public method() : void; } } -/* @@@ label Error SyntaxError: Local class or interface declaration members can not have access modifies. */ -/* @@? 20:36 Error TypeError: Only abstract or native methods can't have body. */ + +/* @@? 18:5 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:9 Error SyntaxError: Local class or interface declaration members can not have access modifies. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_already_class.ets b/ets2panda/test/ast/parser/ets/local_class_already_class.ets index 966c2505b1..3bfff8e7d3 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_class.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_class.ets @@ -22,5 +22,5 @@ function bar(): void { } } -/* @@? 20:9 Error TypeError: Variable 'BC' has already been declared. */ -/* @@? 20:9 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ +/* @@? 17:3 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 20:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_already_interface.ets b/ets2panda/test/ast/parser/ets/local_class_already_interface.ets index 9b4408d291..e9fea16e52 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_interface.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_interface.ets @@ -22,5 +22,4 @@ function bar(): void { } } -/* @@? 20:9 Error TypeError: Variable 'BC' has already been declared. */ -/* @@? 20:9 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ +/* @@? 20:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_already_variable.ets b/ets2panda/test/ast/parser/ets/local_class_already_variable.ets index b9523088d0..c784418b2c 100644 --- a/ets2panda/test/ast/parser/ets/local_class_already_variable.ets +++ b/ets2panda/test/ast/parser/ets/local_class_already_variable.ets @@ -20,5 +20,4 @@ function bar(): void { } } -/* @@? 18:9 Error TypeError: Variable 'BC' has already been declared. */ -/* @@? 18:9 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ +/* @@? 18:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets b/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets index c81cd8a8b2..7ae5c158df 100644 --- a/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets +++ b/ets2panda/test/ast/parser/ets/local_class_in_classfunction.ets @@ -49,13 +49,13 @@ class A_class{ } } -/* @@? 21:24 Error TypeError: Property 'localfield' of enclosing class 'A_class' is not allowed to be captured from the local class 'LocalClass' */ -/* @@? 21:24 Error TypeError: Property 'localfield' must be accessed through 'this' */ -/* @@? 26:29 Error TypeError: Property 'localfield' does not exist on type 'FinalLocalClass' */ -/* @@? 30:41 Error TypeError: Cannot inherit with 'final' modifier. */ -/* @@? 31:53 Error TypeError: Cannot use both 'final' and 'abstract' modifiers. */ -/* @@? 36:37 Error TypeError: AbstractLocalClass2 is abstract therefore cannot be instantiated. */ -/* @@? 39:13 Error TypeError: Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier. */ -/* @@? 40:31 Error TypeError: Native, Abstract and Declare methods cannot have body. */ -/* @@? 43:65 Error TypeError: FinalLocalClass2 is not abstract and does not override abstract method method3(): void in FinalLocalClass2 */ -/* @@? 45:13 Error TypeError: Non abstract class has abstract method. */ \ No newline at end of file +/* @@? 18:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 19:9 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 24:15 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 30:9 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 31:24 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 33:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 36:15 Error TypeError: Cannot find type 'AbstractLocalClass2'. */ +/* @@? 36:41 Error TypeError: Cannot find type 'AbstractLocalClass2'. */ +/* @@? 38:18 Error SyntaxError: Illegal start of CLASS expression. */ +/* @@? 43:15 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/ast/parser/ets/local_interface_already_class.ets b/ets2panda/test/ast/parser/ets/local_interface_already_class.ets index 92b9a2983a..a1458dd771 100644 --- a/ets2panda/test/ast/parser/ets/local_interface_already_class.ets +++ b/ets2panda/test/ast/parser/ets/local_interface_already_class.ets @@ -22,5 +22,4 @@ function bar(): void { } } -/* @@? 20:3 Error TypeError: Variable 'BC' has already been declared. */ -/* @@? 20:3 Error TypeError: Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase! */ +/* @@? 17:3 Error SyntaxError: Illegal start of CLASS expression. */ diff --git a/ets2panda/test/parser/ets/local-class-expected.txt b/ets2panda/test/parser/ets/local-class-expected.txt deleted file mode 100644 index 2936ab5208..0000000000 --- a/ets2panda/test/parser/ets/local-class-expected.txt +++ /dev/null @@ -1,481 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "local-class.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "local-class.ets" - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "local-class.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "local-class.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "returnType": { - "type": "ETSPrimitiveType", - "loc": { - "start": { - "line": 16, - "column": 19, - "program": "local-class.ets" - }, - "end": { - "line": 16, - "column": 22, - "program": "local-class.ets" - } - } - }, - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "LocalClass", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 11, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 21, - "program": "local-class.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 23, - "program": "local-class.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 23, - "program": "local-class.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 23, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 23, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 23, - "program": "local-class.ets" - }, - "end": { - "line": 18, - "column": 23, - "program": "local-class.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "local-class.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 5, - "program": "local-class.ets" - }, - "end": { - "line": 19, - "column": 11, - "program": "local-class.ets" - } - } - }, - { - "type": "ReturnStatement", - "argument": { - "type": "NumberLiteral", - "value": 0, - "loc": { - "start": { - "line": 19, - "column": 12, - "program": "local-class.ets" - }, - "end": { - "line": 19, - "column": 13, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 19, - "column": 5, - "program": "local-class.ets" - }, - "end": { - "line": 19, - "column": 14, - "program": "local-class.ets" - } - } - } - ], - "loc": { - "start": { - "line": 17, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 20, - "column": 2, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "local-class.ets" - }, - "end": { - "line": 20, - "column": 2, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 10, - "program": "local-class.ets" - }, - "end": { - "line": 20, - "column": 2, - "program": "local-class.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 20, - "column": 2, - "program": "local-class.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "local-class.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "local-class.ets" - }, - "end": { - "line": 20, - "column": 2, - "program": "local-class.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/local-class.ets b/ets2panda/test/parser/ets/local-class.ets deleted file mode 100644 index 94e03361a4..0000000000 --- a/ets2panda/test/parser/ets/local-class.ets +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2024-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. - */ - -function main() : int -{ - class LocalClass { } - return 0; -} \ No newline at end of file diff --git a/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt b/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt deleted file mode 100644 index aeb1fbbf32..0000000000 --- a/ets2panda/test/parser/ets/localClassIsPermitted-expected.txt +++ /dev/null @@ -1,672 +0,0 @@ -{ - "type": "Program", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Klass", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 7, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 12, - "program": "localClassIsPermitted.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "ClassStaticBlock", - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": true, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [ - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "Local", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 15, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 20, - "program": "localClassIsPermitted.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 18, - "column": 22, - "program": "localClassIsPermitted.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 18, - "column": 21, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 21, - "column": 6, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 18, - "column": 9, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 21, - "column": 6, - "program": "localClassIsPermitted.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "loc": { - "start": { - "line": 21, - "column": 5, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 21, - "column": 6, - "program": "localClassIsPermitted.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - } - } - }, - "kind": "constructor", - "static": false, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "constructor", - "decorators": [], - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 16, - "column": 14, - "program": "localClassIsPermitted.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - } - ], - "loc": { - "start": { - "line": 16, - "column": 13, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 23, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 16, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 23, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - { - "type": "ClassDeclaration", - "definition": { - "id": { - "type": "Identifier", - "name": "ETSGLOBAL", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "superClass": null, - "implements": [], - "body": [ - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "main", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - { - "type": "MethodDefinition", - "key": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "kind": "method", - "accessibility": "public", - "static": true, - "optional": false, - "computed": false, - "value": { - "type": "FunctionExpression", - "function": { - "type": "ScriptFunction", - "id": { - "type": "Identifier", - "name": "_$init$_", - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": null - }, - "end": { - "line": 1, - "column": 1, - "program": null - } - } - }, - "generator": false, - "async": false, - "expression": false, - "params": [], - "body": { - "type": "BlockStatement", - "statements": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "overloads": [], - "decorators": [], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - }, - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } - } - ], - "loc": { - "start": { - "line": 1, - "column": 1, - "program": "localClassIsPermitted.ets" - }, - "end": { - "line": 23, - "column": 1, - "program": "localClassIsPermitted.ets" - } - } -} diff --git a/ets2panda/test/parser/ets/localClassIsPermitted.ets b/ets2panda/test/parser/ets/localClassIsPermitted.ets deleted file mode 100644 index 85aa2cd787..0000000000 --- a/ets2panda/test/parser/ets/localClassIsPermitted.ets +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2024-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 Klass { - static { - class Local { - - } - } -} diff --git a/ets2panda/test/runtime/ets/InterfaceInBlock.ets b/ets2panda/test/runtime/ets/InterfaceInBlock.ets deleted file mode 100644 index 793e09c283..0000000000 --- a/ets2panda/test/runtime/ets/InterfaceInBlock.ets +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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. - */ - -{ - interface I - { - foo(): int; - } - - class C implements I - { - foo(): int - { - return 1; - } - } - - arktest.assertEQ(new C().foo(), 1); -} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/lambdaWithLocalClassAccess.ets b/ets2panda/test/runtime/ets/lambdaWithLocalClassAccess.ets deleted file mode 100644 index 3358bc6024..0000000000 --- a/ets2panda/test/runtime/ets/lambdaWithLocalClassAccess.ets +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2024-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. - */ - -function f() { - class C { - x: boolean = true - } - let lam = (c: C): boolean => { return c.x } - arktest.assertTrue(lam(new C())) -} - -function main() { - f() -} diff --git a/ets2panda/test/runtime/ets/lambda_with_default.ets b/ets2panda/test/runtime/ets/lambda_with_default.ets deleted file mode 100644 index ec2260dd6d..0000000000 --- a/ets2panda/test/runtime/ets/lambda_with_default.ets +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2024-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. - */ - -function main() { - ()=> { - class A { - foo(x :String ="aa"){ - return x; - } - } - } - arktest.assertTrue(true) -} diff --git a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-boxing.ets deleted file mode 100644 index a5821cacb6..0000000000 --- a/ets2panda/test/runtime/ets/local-class-capture-boxing.ets +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2021-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 UserClassType -{ - v : int = 0; - constructor (p : int) - { - this.v = p; - } - - override toString() : string { - return Int.valueOf(this.v).toString(); - } -} - -enum UserEnumType -{ - Red, - Green, - Blue -}; - -let g_array : int [] = [1,2,3]; -let g_array2 : int [] = [11,12,13]; -let g_Array : Array = new Array(new Int(4), new Int(5), new Int(6)); -let g_Array2 : Array = new Array(new Int(14), new Int(15), new Int(16)); -let g_Object : Object = new Object(); -let g_Object2 : Object = new Object(); -let g_Class : UserClassType = new UserClassType(25); -let g_Class2 : UserClassType = new UserClassType(250); - - - -class GlobalClass -{ - static s_field : int = 13; - field : int = 14; - - static s_method_boxing_local_class() { - // predefined value types - let l_number : number = 1; - let l_byte : byte = 2; - let l_short : short = 3; - let l_int : int = 4; - let l_long : long = 5; - let l_float : float = 6.0f; - let l_double : double = 7.0; - let l_boolean : boolean = false; - let l_char : char = c'x'; - - // user defined value types - let l_enum : UserEnumType = UserEnumType.Red; - - // predefined reference types - let l_Number : Number = new Number(11); - let l_Byte : Byte = new Byte(12 as byte); - let l_Short : Short = new Short(13 as short); - let l_Int : Int = new Int(14 as int); - let l_Long : Long = new Long(15 as long); - let l_Float : Float = new Float(16.0); - let l_Double : Double = new Double(17.0); - let l_Boolean: Boolean = new Boolean(false); - let l_Char : Char = new Char(c'X'); - - let l_string : string = "something"; - let l_String : String = new String("Something"); - let l_array : int [] = g_array; - let l_Array : Array = g_Array; - //let l_bigint : bigint = 20n; - //let l_BigInt : BigInt = new BigInt(21n); - let l_Object : Object = g_Object; - - // user defined reference types - let l_Class : UserClassType = g_Class; - - class LocalClassBoxing - { - local_field : int = 1000; - static local_s_field : int = 2000; - - static local_s_method(lp : int) : void - { - arktest.assertEQ(lp, 300) - arktest.assertEQ(LocalClassBoxing.local_s_field, 2000) - - LocalClassBoxing.local_s_field = 5000; - arktest.assertEQ(LocalClassBoxing.local_s_field, 5000) - } - - local_method(lp : int) : void - { - // Parameter - arktest.assertEQ(lp, 400) - // Local class object field - arktest.assertEQ(this.local_field, 1000) - // Local class static field - arktest.assertEQ(LocalClassBoxing.local_s_field, 5000) - // Outer class static field - arktest.assertEQ(GlobalClass.s_field, 13) - // Predefined value types - arktest.assertEQ(l_number, 1) - arktest.assertEQ(l_byte, 2) - arktest.assertEQ(l_short, 3) - arktest.assertEQ(l_int, 4) - arktest.assertEQ(l_long, 5) - arktest.assertEQ(l_float, 6) - arktest.assertEQ(l_double, 7) - arktest.assertEQ(l_boolean, false) - arktest.assertEQ(l_char, c'x') - // User defined value type - arktest.assertEQ(l_enum, UserEnumType.Red) - // Predefined reference types - arktest.assertEQ(l_Number, Number.valueOf(11)) - arktest.assertEQ(l_Byte, Byte.valueOf(12 as byte)) - arktest.assertEQ(l_Short, Short.valueOf(13 as short)) - arktest.assertEQ(l_Int, Int.valueOf(14 as int)) - arktest.assertEQ(l_Long, Long.valueOf(15 as long)) - arktest.assertEQ(l_Float, Float.valueOf(16 as float)) - arktest.assertEQ(l_Double, Double.valueOf(17 as double)) - arktest.assertEQ(l_Boolean, Boolean.valueOf(false)) - arktest.assertEQ(l_Char, Char.valueOf(c'X')) - arktest.assertEQ(l_string, "something") - arktest.assertEQ(l_String, "Something") - // arktest.assertEQ(l_array, g_array) - // arktest.assertEQ(l_Array, g_Array) - arktest.assertEQ(l_Object, g_Object) - arktest.assertEQ(l_Class, g_Class) - - this.local_field = 1100; - LocalClassBoxing.local_s_field = 5100; - - l_number = 101; - l_byte = 102; - l_short = 103; - l_int = 104; - l_long = 105; - l_float = Double.toFloat(106.0); - l_double = 107.0; - l_boolean = true; - l_char = c'y'; - //l_enum = UserEnumType.Green; - - l_Number = new Number(111); - l_Byte = new Byte(112 as byte); - l_Short = new Short(113 as short); - l_Int = new Int(114 as int); - l_Long = new Long(115 as long); - l_Float = new Float(116.0); - l_Double = new Double(117.0); - l_Boolean = new Boolean(true); - l_Char = new Char(c'Y'); - - l_string = "something new"; - l_String = new String("Something new"); - l_array = g_array2; - l_Array = g_Array2; - l_Object = g_Object2; - l_Class = g_Class2; - } - }; - LocalClassBoxing.local_s_field = 2000; // due to the jit loop - LocalClassBoxing.local_s_method(300); - - let lcb = new LocalClassBoxing(); - lcb.local_method(400); - - arktest.assertEQ(lcb.local_field, 1100) - arktest.assertEQ(LocalClassBoxing.local_s_field, 5100) - arktest.assertEQ(l_number, 101) - arktest.assertEQ(l_byte, 102) - arktest.assertEQ(l_short, 103) - arktest.assertEQ(l_int, 104) - arktest.assertEQ(l_long, 105) - arktest.assertEQ(l_float, 106) - arktest.assertEQ(l_double, 107) - arktest.assertEQ(l_boolean, true) - arktest.assertEQ(l_char, c'y') - - //arktest.assertEQ(l_enum, UserEnumType.Green) - - // Predefined reference types - arktest.assertEQ(l_Number, Number.valueOf(111)) - arktest.assertEQ(l_Byte, Byte.valueOf(112 as byte)) - arktest.assertEQ(l_Short, Short.valueOf(113 as short)) - arktest.assertEQ(l_Int, Int.valueOf(114 as int)) - arktest.assertEQ(l_Long, Long.valueOf(115 as long)) - arktest.assertEQ(l_Float, Float.valueOf(116 as float)) - arktest.assertEQ(l_Double, Double.valueOf(117 as double)) - arktest.assertEQ(l_Boolean, Boolean.valueOf(true)) - arktest.assertEQ(l_Char, Char.valueOf(c'Y')) - arktest.assertEQ(l_string, "something new") - arktest.assertEQ(l_String, "Something new") - //arktest.assertEQ(l_array, g_array2) - //arktest.assertEQ(l_Array, g_Array2) - arktest.assertEQ(l_Object, g_Object2) - arktest.assertEQ(l_Class, g_Class2) - } -} - - -function main() : int -{ - GlobalClass.s_method_boxing_local_class(); - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets b/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets deleted file mode 100644 index 9d477c5e7c..0000000000 --- a/ets2panda/test/runtime/ets/local-class-capture-not-boxing.ets +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2021-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 UserClassType -{ - v : int = 0; - constructor (p : int) - { - this.v = p; - } - - override toString() : string { - return Int.valueOf(this.v).toString(); - } -} - -enum UserEnumType -{ - Red, - Green, - Blue -}; - -let g_array : int [] = [1,2,3]; -let g_array2 : int [] = [11,12,13]; -let g_Array : Array = new Array(new Int(4), new Int(5), new Int(6)); -let g_Array2 : Array = new Array(new Int(14), new Int(15), new Int(16)); -let g_Object : Object = new Object(); -let g_Object2 : Object = new Object(); -let g_Class : UserClassType = new UserClassType(25); -let g_Class2 : UserClassType = new UserClassType(250); - - - -class GlobalClass -{ - static s_field : int = 13; - field : int = 14; - - static s_method_not_boxing_local_class() { - // predefined value types - let l_number : number = 1; - let l_byte : byte = 2; - let l_short : short = 3; - let l_int : int = 4; - let l_long : long = 5; - let l_float : float = 6.0f; - let l_double : double = 7.0; - let l_boolean : boolean = false; - let l_char : char = c'x'; - - // user defined value types - let l_enum : UserEnumType = UserEnumType.Red; - - // predefined reference types - let l_Number : Number = new Number(11); - let l_Byte : Byte = new Byte(12 as byte); - let l_Short : Short = new Short(13 as short); - let l_Int : Int = new Int(14 as int); - let l_Long : Long = new Long(15 as long); - let l_Float : Float = new Float(16.0); - let l_Double : Double = new Double(17.0); - let l_Boolean: Boolean = new Boolean(false); - let l_Char : Char = new Char(c'X'); - - let l_string : string = "something"; - let l_String : String = new String("Something"); - let l_array : int [] = g_array; - let l_Array : Array = g_Array; - //let l_bigint : bigint = 20n; - //let l_BigInt : BigInt = new BigInt(21n); - let l_Object : Object = g_Object; - - // user defined reference types - let l_Class : UserClassType = g_Class; - - class LocalClassNotBoxing - { - local_field : int = 100; - static local_s_field : int = 200; - - static local_s_method(lp : int) : void - { - arktest.assertEQ(lp, 30) - arktest.assertEQ(LocalClassNotBoxing.local_s_field, 200) - } - - local_method(lp : int) : void - { - // Parameter - arktest.assertEQ(lp, 40) - // Local class object field - arktest.assertEQ(this.local_field, 100) - // Local class static field - arktest.assertEQ(LocalClassNotBoxing.local_s_field, 200) - // Predefined value types - arktest.assertEQ(l_number, 1) - arktest.assertEQ(l_byte, 2) - arktest.assertEQ(l_short, 3) - arktest.assertEQ(l_int, 4) - arktest.assertEQ(l_long, 5) - arktest.assertEQ(l_float, 6) - arktest.assertEQ(l_double, 7) - arktest.assertEQ(l_boolean, false) - arktest.assertEQ(l_char, c'x') - // User defined value type - arktest.assertEQ(l_enum, UserEnumType.Red) - // Predefined reference types - arktest.assertEQ(l_Number, Number.valueOf(11)) - arktest.assertEQ(l_Byte, Byte.valueOf(12 as byte)) - arktest.assertEQ(l_Short, Short.valueOf(13 as short)) - arktest.assertEQ(l_Int, Int.valueOf(14 as int)) - arktest.assertEQ(l_Long, Long.valueOf(15 as long)) - arktest.assertEQ(l_Float, Float.valueOf(16 as float)) - arktest.assertEQ(l_Double, Double.valueOf(17 as double)) - arktest.assertEQ(l_Boolean, Boolean.valueOf(false)) - arktest.assertEQ(l_Char, Char.valueOf(c'X')) - arktest.assertEQ(l_string, "something") - arktest.assertEQ(l_String, "Something") - arktest.assertEQ(l_array, g_array) - arktest.assertEQ(l_Array, g_Array) - arktest.assertEQ(l_Object, g_Object) - arktest.assertEQ(l_Class, g_Class) - } - }; - - LocalClassNotBoxing.local_s_method(30); - - let lc = new LocalClassNotBoxing(); - lc.local_method(40); - } -} - - -function main() : int -{ - GlobalClass.s_method_not_boxing_local_class(); - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-capture-parameter.ets b/ets2panda/test/runtime/ets/local-class-capture-parameter.ets deleted file mode 100644 index 5ca80d7d79..0000000000 --- a/ets2panda/test/runtime/ets/local-class-capture-parameter.ets +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021-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 GlobalClass -{ - static capture_param_method(param : int) - { - class LocalClass - { - method() - { - arktest.assertEQ(param, 1) - } - } - - let lc = new LocalClass(); - lc.method() - } -} - -function main() : int -{ - GlobalClass.capture_param_method(1); - - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-in-local-class.ets b/ets2panda/test/runtime/ets/local-class-in-local-class.ets deleted file mode 100644 index 6b00db07b3..0000000000 --- a/ets2panda/test/runtime/ets/local-class-in-local-class.ets +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021-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. - */ - - -function main() : int -{ - let l_int = 0; - - class LocalClassLevel1 - { - m_int1 = 11; - - method1() - { - let l_int2 = 12; - arktest.assertEQ(this.m_int1, 11) - arktest.assertEQ(l_int, 0) - l_int = 1; - - class LocalClassLevel2 - { - m_int2 : int = 22; - - method2() { - arktest.assertEQ(this.m_int2, 22) - arktest.assertEQ(l_int2, 12) - l_int2 = 13; - } - } - - let lcl2 = new LocalClassLevel2(); - lcl2.method2(); - arktest.assertEQ(l_int2, 13) - } - } - - let lcl1 = new LocalClassLevel1(); - lcl1.method1(); - arktest.assertEQ(l_int, 1) - - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-mixed-capture.ets b/ets2panda/test/runtime/ets/local-class-mixed-capture.ets deleted file mode 100644 index 6456d9b22a..0000000000 --- a/ets2panda/test/runtime/ets/local-class-mixed-capture.ets +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021-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. - */ - -function main() : int -{ - // Since the BoxingLocalClass modifies the 'i' it has to be boxed and use it as a boxed - // variable in the NotBoxingLocalClass too - let i : int = 1; - - class NotBoxingLocalClass - { - local_method() - { - arktest.assertEQ(i, 1) - } - } - - class BoxingLocalClass - { - local_method() - { - arktest.assertEQ(i, 1) - i = 2; - } - } - - let nblc = new NotBoxingLocalClass(); - nblc.local_method(); - - let blc = new BoxingLocalClass(); - blc.local_method(); - arktest.assertEQ(i, 2) - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets b/ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets deleted file mode 100644 index 706a7b6836..0000000000 --- a/ets2panda/test/runtime/ets/local-class-modify-captured-parameter.ets +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021-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 GlobalClass -{ - static capture_param_method(param : int) - { - class LocalClass - { - method() - { - arktest.assertEQ(param, 1) - param = 3; - } - } - - let lc = new LocalClass(); - lc.method() - arktest.assertEQ(param, 3) - } -} - -function main() : int -{ - GlobalClass.capture_param_method(1); - - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-standard-example1.ets b/ets2panda/test/runtime/ets/local-class-standard-example1.ets deleted file mode 100644 index 3e668fdc9f..0000000000 --- a/ets2panda/test/runtime/ets/local-class-standard-example1.ets +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2021-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. - */ - -function foo (parameter: number) { - let local: string = "function local"; - interface LocalInterface { // Local interface in a top-level function - method (): void; // It has a method - field: string; // and a property - } - class LocalClass implements LocalInterface { // Class implements interface - // Local class in a top-level function - override method () { - console.log ("Instance field = " + this.field + " par = " + parameter + " loc = " + local ) - arktest.assertEQ(this.field, "`instance field value`") - arktest.assertEQ(parameter, 42) - arktest.assertEQ(local, "function local") - } - field: string = "`instance field value`" - static s_method () { - console.log ("Static field = " + LocalClass.s_field) - arktest.assertEQ(LocalClass.s_field, "`class/static field value`") - - } - static s_field: string = "`class/static field value`" - } - - let lc: LocalInterface = new LocalClass(); - // Both local types can be freely used in the top-level function scope - lc.method() - LocalClass.s_method() -} - -function main() : int -{ - foo(42); - return 0; -} diff --git a/ets2panda/test/runtime/ets/local-class-standard-example2.ets b/ets2panda/test/runtime/ets/local-class-standard-example2.ets deleted file mode 100644 index 8d6505f4e6..0000000000 --- a/ets2panda/test/runtime/ets/local-class-standard-example2.ets +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2021-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 A_class { - field: number = 1234 // Not visible for the local class - method (parameter: number) { - let local: string = "instance local" - - interface LocalInterface { - method (): void - field: string - } - - class LocalClass implements LocalInterface { - override method () { - console.log ("Instance field = " + this.field + " par = " + parameter + " loc = " + local ) - arktest.assertEQ(this.field, "`instance method instance field value`") - arktest.assertEQ(parameter, 42) - arktest.assertEQ(local, "instance local") - - } - field: string = "`instance method instance field value`" - static s_method () { - console.log ("Static field = " + LocalClass.s_field) - arktest.assertEQ(LocalClass.s_field, "`instance method class/static field value`") - } - static s_field: string = "`instance method class/static field value`" - } - - let lc: LocalInterface = new LocalClass - lc.method() - LocalClass.s_method() - } - - static s_method (parameter: number) { - let local: string = "class/static local" - interface LocalInterface { - method (): void - field: string - } - - class LocalClass implements LocalInterface { - override method () { - console.log ("Instance field = " + this.field + " par = " + parameter + " loc = " + local) - arktest.assertEQ(this.field, "`static method instance field value`") - arktest.assertEQ(parameter, 72) - arktest.assertEQ(local, "class/static local") - } - field: string = "`static method instance field value`" - static s_method () { - console.log ("Static field = " + LocalClass.s_field) - arktest.assertEQ(LocalClass.s_field, "`static method class/static field value`") - } - static s_field: string = "`static method class/static field value`" - } - let lc: LocalInterface = new LocalClass - lc.method() - LocalClass.s_method() - } -} - -function main() : int -{ - A_class.s_method(72); - - let a = new A_class(); - a.method(42) - - return 0; -} diff --git a/ets2panda/test/runtime/ets/local_class_in_classfunction.ets b/ets2panda/test/runtime/ets/local_class_in_classfunction.ets deleted file mode 100644 index 511ba88cee..0000000000 --- a/ets2panda/test/runtime/ets/local_class_in_classfunction.ets +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2024-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 A_class{ - foo(){ - let localfield:string = "localstring"; - abstract class AbstractLocalClass{ - field1:int = 100; - } - class LocalClass extends AbstractLocalClass{ - field2:int = 200; - static staticfield = 300; - method1(){ - arktest.assertEQ(this.field1, 100) - arktest.assertEQ(this.field2, 200) - arktest.assertEQ(localfield, "localstring") - } - static method2(){ - arktest.assertEQ(LocalClass.staticfield, 300) - } - } - final class FinalLocalClass{ - field1:int = 100; - static staticfield = 300; - method1(){ - arktest.assertEQ(this.field1, 100) - arktest.assertEQ(localfield, "localstring") - } - static method2(){ - arktest.assertEQ(LocalClass.staticfield, 300) - } - } - - let x:AbstractLocalClass = new LocalClass(); - arktest.assertEQ(x.field1, 100) - arktest.assertEQ(x.field2, 200) - arktest.assertEQ(LocalClass.staticfield, 300) - x.method1(); - LocalClass.method2(); - - let x2:FinalLocalClass = new FinalLocalClass(); - arktest.assertEQ(x2.field1, 100) - arktest.assertEQ(FinalLocalClass.staticfield, 300) - x2.method1() - FinalLocalClass.method2(); - } -} - -function main():void -{ - let x3:A_class = new A_class; - x3.foo(); -} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/local_class_in_function.ets b/ets2panda/test/runtime/ets/local_class_in_function.ets deleted file mode 100644 index 1433c62871..0000000000 --- a/ets2panda/test/runtime/ets/local_class_in_function.ets +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2024-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. - */ -function main():void -{ - let localint:int = 200; - - abstract class AbstractLocalClass{ - field1:int = 10; - } - - class LocalClass extends AbstractLocalClass{ - field2:int = 20; - static staticfield = 30; - method1(){ - arktest.assertEQ(this.field1, 10) - arktest.assertEQ(this.field2, 20) - arktest.assertEQ(localint, 200) - } - static method2(){ - arktest.assertEQ(LocalClass.staticfield, 30) - } - } - - final class FinalLocalClass{ - field1:int = 10; - static staticfield = 30; - method1(){ - arktest.assertEQ(this.field1, 10) - arktest.assertEQ(localint, 200) - } - static method2(){ - arktest.assertEQ(FinalLocalClass.staticfield, 30) - } - } - - let x:AbstractLocalClass = new LocalClass(); - arktest.assertEQ(x.field1, 10) - arktest.assertEQ(x.field2, 20) - arktest.assertEQ(LocalClass.staticfield, 30) - x.method1(); - LocalClass.method2(); - - let x2:FinalLocalClass = new FinalLocalClass(); - arktest.assertEQ(x2.field1, 10) - arktest.assertEQ(FinalLocalClass.staticfield, 30) - x2.method1() - FinalLocalClass.method2(); -} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/statement_after_local_class.ets b/ets2panda/test/runtime/ets/statement_after_local_class.ets deleted file mode 100644 index db15a0eb86..0000000000 --- a/ets2panda/test/runtime/ets/statement_after_local_class.ets +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2024-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. - */ - -function main(): void { - class MyClass { - constructor() { - } - - foo(): number { - return 1.0 - } - } - - let m = new MyClass() - - arktest.assertEQ(m.foo(), 1.0) -} diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 00b73cae26..2034b92c73 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -168,9 +168,9 @@ syntax: id: 39 message: "A try statement should contain either finally clause or at least one catch clause." -- name: ILLEGAL_START_STRUCT +- name: ILLEGAL_START_STRUCT_CLASS id: 40 - message: "Illegal start of STRUCT expression." + message: "Illegal start of {} expression." - name: ONLY_EXPORT_CLASS_OR_INTERFACE id: 41 -- Gitee From 2d3f68a8e2f323caacc1c4e05db9cb7894dc216b Mon Sep 17 00:00:00 2001 From: oh-rgx Date: Wed, 2 Jul 2025 21:13:36 +0800 Subject: [PATCH 038/107] Fix binaryExpr type Issue: #ICJK0E Signed-off-by: oh-rgx --- ets2panda/checker/ets/arithmetic.cpp | 10 ---- .../ast/compiler/ets/bigInt_operators_neg.ets | 50 ++++++++++++++++ .../test/runtime/ets/bigInt_operators_pos.ets | 57 +++++++++++++++++++ 3 files changed, 107 insertions(+), 10 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets create mode 100644 ets2panda/test/runtime/ets/bigInt_operators_pos.ets diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index cbe2c38d4e..24dde9d0c0 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -224,16 +224,6 @@ bool ETSChecker::CheckBinaryOperatorForBigInt(Type *left, Type *right, lexer::To case lexer::TokenType::PUNCTUATOR_LESS_THAN_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: - case lexer::TokenType::PUNCTUATOR_PLUS: - case lexer::TokenType::PUNCTUATOR_MINUS: - case lexer::TokenType::PUNCTUATOR_MULTIPLY: - case lexer::TokenType::PUNCTUATOR_DIVIDE: - case lexer::TokenType::PUNCTUATOR_MOD: - case lexer::TokenType::PUNCTUATOR_BITWISE_OR: - case lexer::TokenType::PUNCTUATOR_BITWISE_AND: - case lexer::TokenType::PUNCTUATOR_BITWISE_XOR: - case lexer::TokenType::PUNCTUATOR_LEFT_SHIFT: - case lexer::TokenType::PUNCTUATOR_RIGHT_SHIFT: return true; default: break; diff --git a/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets b/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets new file mode 100644 index 0000000000..5ea74fcbfb --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/bigInt_operators_neg.ets @@ -0,0 +1,50 @@ +/* + * 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. + */ + +const v0 = 1516532564n; +const vStr = "Weens" +for (const v2 of vStr) { + for (let v3 = 0; v3< 93; v3++) { + const v4 = [-3.0, -921192.1546513135, -1000000.0, 0.21581641635431563, NaN, 1e-15, -1e-15, -28.514616541534]; + } + const v1 = 545314157; + const gtTest = v1 > v0; + const ltTest = v1 < v0; + const gteTest = v1 >= v0; + const lteTest = v1 <= v0; + const eqTest = v1 == v0; + const neqTest = v1 != v0; + const addTest = v1 + v0; + const subTest = v1 - v0; + const mulTest = v1 * v0; + const divTest = v1 / v0; + const modTest = v1 % v0; + const bitOrTest = v1 | v0; + const bitAndTest = v1 & v0; + const bitXorTest = v1 ^ v0; + const rightTest = v1 >> v0; + const leftTest = v1 << v0; +} + +/* @@? 29:21 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ +/* @@? 30:21 Error TypeError: Bad operand type, the types of the operands must be numeric type, enum or String. */ +/* @@? 31:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 32:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 33:21 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 34:23 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 35:24 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 36:24 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 37:23 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 38:22 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ diff --git a/ets2panda/test/runtime/ets/bigInt_operators_pos.ets b/ets2panda/test/runtime/ets/bigInt_operators_pos.ets new file mode 100644 index 0000000000..45741b4806 --- /dev/null +++ b/ets2panda/test/runtime/ets/bigInt_operators_pos.ets @@ -0,0 +1,57 @@ +/* + * 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. + */ + +const v0 = 123n; +const vStr = "Weens" +for (const v2 of vStr) { + for (let v3 = 0; v3< 93; v3++) { + const v4 = [-3.0, -921192.1546513135, -1000000.0, 0.21581641635431563, NaN, 1e-15, -1e-15, -28.514616541534]; + } + const v1 = 1n; + const gtTest = v1 > v0; + const ltTest = v1 < v0; + const gteTest = v1 >= v0; + const lteTest = v1 <= v0; + const eqTest = v1 == v0; + const neqTest = v1 != v0; + const addTest = v1 + v0; + const subTest = v1 - v0; + const mulTest = v1 * v0; + const divTest = v1 / v0; + const modTest = v1 % v0; + const bitOrTest = v1 | v0; + const bitAndTest = v1 & v0; + const bitXorTest = v1 ^ v0; + const rightTest = v1 >> v0; + const leftTest = v1 << v0; + + arktest.assertEQ(gtTest, false); + arktest.assertEQ(ltTest, true); + arktest.assertEQ(gteTest, false); + arktest.assertEQ(lteTest, true); + arktest.assertEQ(eqTest, false); + arktest.assertEQ(neqTest, true); + + arktest.assertEQ(addTest, 124n); + arktest.assertEQ(subTest, -122n); + arktest.assertEQ(mulTest, 123n); + arktest.assertEQ(divTest, 0n); + arktest.assertEQ(modTest, 1n ); + arktest.assertEQ(bitOrTest, 123n); + arktest.assertEQ(bitAndTest, 1n); + arktest.assertEQ(bitXorTest, 122n); + arktest.assertEQ(rightTest, 0n); + arktest.assertEQ(leftTest, 10633823966279326983230456482242756608n); +} -- Gitee From 2a3941c15c4fd43634a5e74f1ad6377032c2e134 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Sat, 5 Jul 2025 16:08:30 +0800 Subject: [PATCH 039/107] Fix crash when create ETSObjectType Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK7C3?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ets/object.cpp | 7 +++-- .../test/ast/compiler/ets/invalid_object.ets | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/invalid_object.ets diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index ad7a332f38..eca2a1c0eb 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -471,9 +471,12 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte interfaceType->SetVariable(var); type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; var->SetTsType(type); - } else { + } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { interfaceType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; + } else { + ES2PANDA_ASSERT(IsAnyError()); + return GlobalTypeError(); } // Save before we mess with savedContext. @@ -525,7 +528,7 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) if (classDef->IsAbstract()) { classType->AddObjectFlag(checker::ETSObjectFlags::ABSTRACT); } - } else if (var->TsType()->IsETSObjectType()) { + } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { classType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(classType) : classType; } else { diff --git a/ets2panda/test/ast/compiler/ets/invalid_object.ets b/ets2panda/test/ast/compiler/ets/invalid_object.ets new file mode 100644 index 0000000000..6d2e5fb2a1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_object.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. + */ + +interface Obj {} +const object1: Obj = {}; + +console.log(Objˆct.keys(object1)); + +/* @@? 19:13 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 19:13 Error TypeError: Class or interface 'Obj' cannot be used as object */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:16 Error SyntaxError: Unexpected token 'ˆct'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:16 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 19:16 Error TypeError: Unresolved reference ˆct */ +/* @@? 19:33 Error SyntaxError: Unexpected token ')'. */ \ No newline at end of file -- Gitee From 25e6916d5c5998bffb90898796ee7149a6c10027 Mon Sep 17 00:00:00 2001 From: pengbiao Date: Sat, 5 Jul 2025 14:37:00 +0800 Subject: [PATCH 040/107] Fix es2panda check variance crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK6TY Signed-off-by: pengbiao --- ets2panda/checker/types/ets/etsObjectType.cpp | 25 +++++++++++++++++-- .../ast/compiler/ets/check_variance_crash.ets | 20 +++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/check_variance_crash.ets diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index e7d2fb4229..e945ae820b 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -1568,8 +1568,29 @@ void ETSObjectType::CheckVarianceRecursively(TypeRelation *relation, VarianceFla return; } - auto *params = GetDeclNode()->IsClassDefinition() ? GetDeclNode()->AsClassDefinition()->TypeParams() - : GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + // according to the spec(GENERICS chapter), only class/interface/function/ + // method/lambda and type alias can have type parameters. since + // 1. the type of function and method is ETSFunctionType + // 2. lambda has been checked above + // here we just need check + // 1. class + // 2. interface + // 3. type alias(which will be redirected to its real type) + // And all of them should have declarations + if (declNode_ == nullptr) { + // If the type is not declared, then we do not need to check variance. + return; + } + ir::TSTypeParameterDeclaration *params; + if (GetDeclNode()->IsClassDefinition()) { + params = GetDeclNode()->AsClassDefinition()->TypeParams(); + } else if (GetDeclNode()->IsTSInterfaceDeclaration()) { + params = GetDeclNode()->AsTSInterfaceDeclaration()->TypeParams(); + } else { + // If the type is not a class or interface or type alias, then we do not need to check variance. + return; + } + if (params == nullptr) { return; } diff --git a/ets2panda/test/ast/compiler/ets/check_variance_crash.ets b/ets2panda/test/ast/compiler/ets/check_variance_crash.ets new file mode 100644 index 0000000000..f5bfa6f468 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/check_variance_crash.ets @@ -0,0 +1,20 @@ +/* + * 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. + */ + +type BreakpointType = 'xs' | 'sm' +class BreakPointState { + public update(type: BreakpointType):void { + } +} -- Gitee From 7a4cc89c6911bde930b07bc6384c4cc38ab8232d Mon Sep 17 00:00:00 2001 From: dongchao Date: Thu, 3 Jul 2025 20:23:55 +0800 Subject: [PATCH 041/107] Fix interface optional scene in declgen_ets2ts Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJU2L Signed-off-by: dongchao Change-Id: I49dbbf9598ba2d46731dba2b58f792eeb7d16d86 --- .../ets/interfacePropertyDeclarations.cpp | 2 + ets2panda/declgen_ets2ts/declgenEts2Ts.cpp | 127 ++++++++++++++---- ets2panda/declgen_ets2ts/declgenEts2Ts.h | 2 + ...est_ets2ts_isolated_interface-expected.txt | 14 +- 4 files changed, 109 insertions(+), 36 deletions(-) diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index b9aafa8736..ee9c32e370 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -218,7 +218,9 @@ ir::Expression *InterfacePropertyDeclarationsPhase::UpdateInterfaceProperties(pu HandleInternalGetterOrSetterMethod(prop); continue; } + auto *originProp = prop->Clone(ctx->allocator, nullptr); auto getter = GenerateGetterOrSetter(ctx, varbinder, prop->AsClassProperty(), false); + getter->SetOriginalNode(originProp); auto methodScope = scope->AsClassScope()->InstanceMethodScope(); auto name = getter->Key()->AsIdentifier()->Name(); diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index 7b37223644..132354d874 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -70,6 +70,8 @@ bool TSDeclGen::GenGlobalDescriptor() OutEndlTs(); OutTs("ETSGLOBAL.", compiler::Signatures::INIT_METHOD, "();"); OutEndlTs(); + OutTs("export {};"); + OutEndlTs(); return true; } @@ -153,7 +155,9 @@ void TSDeclGen::ProcessClassDependencies(const ir::ClassDeclaration *classDecl) if (state_.super != nullptr) { AddSuperType(state_.super); } - ProcessInterfacesDependencies(classDef->TsType()->AsETSObjectType()->Interfaces()); + if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType()) { + ProcessInterfacesDependencies(classDef->TsType()->AsETSObjectType()->Interfaces()); + } if (classDef->TypeParams() != nullptr) { GenSeparated( @@ -212,6 +216,9 @@ void TSDeclGen::ProcessClassMethodDependencies(const ir::MethodDefinition *metho void TSDeclGen::AddSuperType(const ir::Expression *super) { + if (super->TsType() == nullptr) { + return; + } const auto superType = checker::ETSChecker::ETSType(super->TsType()); if (superType == checker::TypeFlag::ETS_OBJECT) { auto objectType = super->TsType()->AsETSObjectType(); @@ -1067,16 +1074,19 @@ void TSDeclGen::GenNamespaceImport(const ir::AstNode *specifier, const std::stri void TSDeclGen::GenDefaultImport(const ir::AstNode *specifier, const std::string &source, bool isTypeKind) { - const auto local = specifier->AsImportDefaultSpecifier()->Local()->Name(); - if (specifier->AsImportDefaultSpecifier()->Local()->Variable() && - specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration() && - specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration()->Node() && - specifier->AsImportDefaultSpecifier()->Local()->Variable()->Declaration()->Node()->IsTSInterfaceDeclaration()) { - OutTs("import type ", local, " from \"", source, "\";"); - } else { - OutTs(isTypeKind ? "import type " : "import ", local, " from \"", source, "\";"); + auto importDefaultSpecifier = specifier->AsImportDefaultSpecifier(); + auto variable = importDefaultSpecifier->Local()->Variable(); + const auto local = importDefaultSpecifier->Local()->Name(); + bool isTypeDeclaration = false; + if (variable != nullptr && variable->Declaration() != nullptr && variable->Declaration()->Node() != nullptr) { + auto *node = variable->Declaration()->Node(); + isTypeDeclaration = node->IsTSTypeAliasDeclaration() || node->IsTSInterfaceDeclaration(); } - OutEndlTs(); + if (!isTypeKind && !isTypeDeclaration) { + OutTs("import ", local, " from \"", source, "\";"); + OutEndlTs(); + } + if (importSet_.find(local.Mutf8()) == importSet_.end()) { return; } @@ -1094,8 +1104,9 @@ void TSDeclGen::GenNamedImports(const ir::ETSImportDeclaration *importDeclaratio std::vector normalSpecifiers; SeparateInterfaceSpecifiers(specifiers, interfaceSpecifiers, normalSpecifiers); - GenTsImportStatement(interfaceSpecifiers, importDeclaration, true); - GenTsImportStatement(normalSpecifiers, importDeclaration); + if (!isTypeKind) { + GenTsImportStatement(normalSpecifiers, importDeclaration); + } auto importSpecifiers = FilterValidImportSpecifiers(specifiers); GenDtsImportStatement(importSpecifiers, importDeclaration, isTypeKind); @@ -1189,8 +1200,9 @@ void TSDeclGen::GenReExportDeclaration(const ir::ETSReExportDeclaration *reExpor GenDtsReExportStatement(specifiers, importDeclaration, isTypeKind); - GenTsReExportStatement(interfaceSpecifiers, importDeclaration, true); - GenTsReExportStatement(normalSpecifiers, importDeclaration); + if (!isTypeKind) { + GenTsReExportStatement(normalSpecifiers, importDeclaration); + } } bool TSDeclGen::GenNamespaceReExportDeclaration(const ir::AstNode *specifier, @@ -1217,10 +1229,14 @@ void TSDeclGen::SeparateInterfaceSpecifiers(const ArenaVector &sp if (!specifier->IsImportSpecifier()) { continue; } - if (specifier->AsImportSpecifier()->Imported()->Variable() && - specifier->AsImportSpecifier()->Imported()->Variable()->Declaration() && - specifier->AsImportSpecifier()->Imported()->Variable()->Declaration()->Node() && - specifier->AsImportSpecifier()->Imported()->Variable()->Declaration()->Node()->IsTSInterfaceDeclaration()) { + auto importSpecifier = specifier->AsImportSpecifier(); + auto variable = importSpecifier->Imported()->Variable(); + bool isTypeDeclaration = false; + if (variable != nullptr && variable->Declaration() != nullptr && variable->Declaration()->Node() != nullptr) { + auto *node = variable->Declaration()->Node(); + isTypeDeclaration = node->IsTSTypeAliasDeclaration() || node->IsTSInterfaceDeclaration(); + } + if (isTypeDeclaration) { interfaceSpecifiers.push_back(specifier); } else { normalSpecifiers.push_back(specifier); @@ -1593,16 +1609,68 @@ void TSDeclGen::GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interf void TSDeclGen::ProcessInterfaceBody(const ir::TSInterfaceBody *body) { - std::unordered_set processedMethods; for (auto *prop : body->Body()) { if (prop->IsMethodDefinition()) { - ProcessMethodDefinition(prop->AsMethodDefinition(), processedMethods); + ProcessInterfaceMethodDefinition(prop->AsMethodDefinition()); } else if (prop->IsClassProperty()) { GenPropDeclaration(prop->AsClassProperty()); } } } +void TSDeclGen::ProcessInterfaceMethodDefinition(const ir::MethodDefinition *methodDef) +{ + if (GenInterfaceProp(methodDef)) { + return; + } + + if (methodDef->IsGetter() || methodDef->IsSetter()) { + GenMethodDeclaration(methodDef); + } + if (!methodDef->Overloads().empty()) { + for (const auto *overloadMethd : methodDef->Overloads()) { + if (overloadMethd->IsGetter() || overloadMethd->IsSetter()) { + GenMethodDeclaration(overloadMethd); + } + } + return; + } + if (!methodDef->IsGetter() && !methodDef->IsSetter()) { + GenMethodDeclaration(methodDef); + } +} + +bool TSDeclGen::GenInterfaceProp(const ir::MethodDefinition *methodDef) +{ + if (!methodDef->IsGetter()) { + return false; + } + if (methodDef->OriginalNode() == nullptr) { + return false; + } + if (!methodDef->OriginalNode()->IsClassProperty()) { + return false; + } + + const auto methodName = GetKeyIdent(methodDef->Key())->Name().Mutf8(); + const auto classProp = methodDef->OriginalNode()->AsClassProperty(); + bool isReadOnly = classProp->IsReadonly(); + bool isOptional = classProp->IsOptionalDeclaration(); + ProcessIndent(); + if (isReadOnly) { + OutDts("readonly "); + } + OutDts(methodName); + if (isOptional) { + OutDts("?"); + } + OutDts(": "); + GenType(methodDef->Function()->Signature()->ReturnType()); + OutDts(";"); + OutEndlDts(); + return true; +} + void TSDeclGen::ProcessMethodDefinition(const ir::MethodDefinition *methodDef, std::unordered_set &processedMethods) { @@ -1668,9 +1736,11 @@ void TSDeclGen::EmitClassDeclaration(const ir::ClassDefinition *classDef, const if (classDef->IsNamespaceTransformed()) { EmitDeclarationPrefix(classDef, "namespace ", className); OutTs("export namespace ", className, " {"); + OutEndlTs(); } else if (classDef->IsEnumTransformed()) { EmitDeclarationPrefix(classDef, "enum ", className); OutTs("export const enum ", className, " {"); + OutEndlTs(); } else if (classDef->IsFromStruct()) { EmitDeclarationPrefix(classDef, "struct ", className); } else if (classDef->IsAbstract()) { @@ -1678,7 +1748,6 @@ void TSDeclGen::EmitClassDeclaration(const ir::ClassDefinition *classDef, const } else { EmitDeclarationPrefix(classDef, "class ", className); } - OutEndlTs(); } std::string TSDeclGen::GetIndent() const @@ -1739,10 +1808,10 @@ void TSDeclGen::HandleClassDeclarationTypeInfo(const ir::ClassDefinition *classD HandleClassInherit(super); } - const auto &interfaces = classDef->TsType()->AsETSObjectType()->Interfaces(); - if (!interfaces.empty()) { + if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType() && + !classDef->TsType()->AsETSObjectType()->Interfaces().empty()) { OutDts(" implements "); - ES2PANDA_ASSERT(classDef->TsType()->IsETSObjectType()); + const auto &interfaces = classDef->TsType()->AsETSObjectType()->Interfaces(); GenSeparated(interfaces, [this](checker::ETSObjectType *interface) { GenType(interface); }); } else if (!classDef->Implements().empty()) { OutDts(" implements "); @@ -1764,7 +1833,7 @@ void TSDeclGen::HandleClassInherit(const ir::Expression *expr) void TSDeclGen::EmitClassGlueCode(const ir::ClassDefinition *classDef, const std::string &className) { - if (classNode_.isIndirect) { + if (classNode_.isIndirect || classDef->IsExportedType()) { return; } const std::string exportPrefix = classDef->Parent()->IsDefaultExported() ? "const " : "export const "; @@ -1837,7 +1906,9 @@ void TSDeclGen::ProcessClassBody(const ir::ClassDefinition *classDef) GenClassDeclaration(prop->AsClassDeclaration()); } } - ProcessMethodsFromInterfaces(processedMethods, classDef->TsType()->AsETSObjectType()->Interfaces()); + if (classDef->TsType() != nullptr && classDef->TsType()->IsETSObjectType()) { + ProcessMethodsFromInterfaces(processedMethods, classDef->TsType()->AsETSObjectType()->Interfaces()); + } } void TSDeclGen::CloseClassBlock(const bool isDts) @@ -2019,7 +2090,9 @@ void TSDeclGen::GenMethodSignature(const ir::MethodDefinition *methodDef, const if (methodDef->TsType() == nullptr) { LogWarning(diagnostic::UNTYPED_METHOD, {methodName}, methodIdent->Start()); OutDts(": any"); - } else { + return; + } + if (methodDef->TsType()->IsETSFunctionType()) { GenFunctionType(methodDef->TsType()->AsETSFunctionType(), methodDef); } } diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.h b/ets2panda/declgen_ets2ts/declgenEts2Ts.h index 850722c6f0..94471dab3b 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.h +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.h @@ -146,6 +146,7 @@ private: void GenTypeAliasDeclaration(const ir::TSTypeAliasDeclaration *typeAlias); void GenEnumDeclaration(const ir::ClassProperty *enumMember); void GenInterfaceDeclaration(const ir::TSInterfaceDeclaration *interfaceDecl); + bool GenInterfaceProp(const ir::MethodDefinition *methodDef); void GenClassDeclaration(const ir::ClassDeclaration *classDecl); void GenMethodDeclaration(const ir::MethodDefinition *methodDef); bool GenMethodDeclarationPrefix(const ir::MethodDefinition *methodDef, const ir::Identifier *methodIdent, @@ -226,6 +227,7 @@ private: void HandleTypeArgument(checker::Type *arg, const std::string &typeStr); void ProcessInterfaceBody(const ir::TSInterfaceBody *body); + void ProcessInterfaceMethodDefinition(const ir::MethodDefinition *methodDef); void ProcessMethodDefinition(const ir::MethodDefinition *methodDef, std::unordered_set &processedMethods); diff --git a/ets2panda/test/unit/declgen/ets2ts_isolated/test_ets2ts_isolated_interface-expected.txt b/ets2panda/test/unit/declgen/ets2ts_isolated/test_ets2ts_isolated_interface-expected.txt index 40f1e96753..072a2020c2 100644 --- a/ets2panda/test/unit/declgen/ets2ts_isolated/test_ets2ts_isolated_interface-expected.txt +++ b/ets2panda/test/unit/declgen/ets2ts_isolated/test_ets2ts_isolated_interface-expected.txt @@ -1,14 +1,10 @@ export declare interface User { - get id(): number; - set id(value: number); - get name(): string; - set name(value: string); - get age(): number | undefined; - set age(value: number | undefined); - get apiUrl(): string; + id: number; + name: string; + age?: number | undefined; + readonly apiUrl: string; } export declare interface Animal { - get name(): string; - set name(value: string); + name: string; makeSound(): void; } -- Gitee From a6b343300e2414674bb17756697374e32965517b Mon Sep 17 00:00:00 2001 From: oh-rgx Date: Sat, 5 Jul 2025 20:28:57 +0800 Subject: [PATCH 042/107] Fix classProperty CTE Issue: #ICK8JQ Signed-off-by: oh-rgx --- ets2panda/checker/ets/object.cpp | 6 +++++ .../ast/compiler/ets/class_inheritance.ets | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/class_inheritance.ets diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index 7cfe16d58e..e1dc7997d0 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -2341,6 +2341,12 @@ void ETSChecker::CheckValidInheritance(ETSObjectType *classType, ir::ClassDefini const auto &allProps = classType->GetAllProperties(); for (auto *it : allProps) { + auto *node = it->Declaration()->Node(); + if (node->IsClassProperty() && node->AsClassProperty()->TsType() != nullptr && + node->AsClassProperty()->TsType()->IsTypeError()) { + continue; + } + const auto searchFlag = PropertySearchFlags::SEARCH_ALL | PropertySearchFlags::SEARCH_IN_BASE | PropertySearchFlags::SEARCH_IN_INTERFACES | PropertySearchFlags::DISALLOW_SYNTHETIC_METHOD_CREATION; diff --git a/ets2panda/test/ast/compiler/ets/class_inheritance.ets b/ets2panda/test/ast/compiler/ets/class_inheritance.ets new file mode 100644 index 0000000000..78e049e51a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/class_inheritance.ets @@ -0,0 +1,25 @@ +/* + * 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 AAA { + objectProp = {name: 'Jone', age: 30}; +} + +class BBB extends AAA { + objectProp = {name: 'Jone', age: 30}; +} + +/* @@? 17:5 Error TypeError: Cannot infer type for objectProp because class composite needs an explicit target type */ +/* @@? 21:5 Error TypeError: Cannot infer type for objectProp because class composite needs an explicit target type */ \ No newline at end of file -- Gitee From 03d9e15efcc5186b86d62edb5f08c065d4767883 Mon Sep 17 00:00:00 2001 From: zmw Date: Sat, 5 Jul 2025 17:36:51 +0800 Subject: [PATCH 043/107] Fix newExpr multi dot crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK7UA Description: Fix nexExpr multi dot crash Signed-off-by: zmw --- ets2panda/parser/ETSparser.cpp | 4 ++++ .../ets/new_expr_with_succesive_multi_dot.ets | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index b64ecbcdb6..9e2059c27d 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1016,6 +1016,10 @@ ir::TypeNode *ETSParser::ParseTypeReference(TypeAnnotationParsingOptions *option while (true) { auto partPos = Lexer()->GetToken().Start(); auto [typeName, typeParams] = ParseTypeReferencePart(options); + if (typeName == nullptr) { + typeName = AllocBrokenExpression(partPos); + } + typeRefPart = AllocNode(typeName, typeParams, typeRefPart, Allocator()); typeRefPart->SetRange({partPos, Lexer()->GetToken().End()}); diff --git a/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets b/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets new file mode 100644 index 0000000000..dc623f5b1a --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/new_expr_with_succesive_multi_dot.ets @@ -0,0 +1,24 @@ +/* + * 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. + */ + +importet lock1 = new ArkTSUt../main; + +/* @@? 16:1 Error TypeError: Unresolved reference importet */ +/* @@? 16:10 Error SyntaxError: Unexpected token 'lock1'. */ +/* @@? 16:10 Error TypeError: Unresolved reference lock1 */ +/* @@? 16:18 Error TypeError: Bad operand type, the types of the operands must be numeric type. */ +/* @@? 16:30 Error SyntaxError: Identifier expected. */ +/* @@? 16:31 Error SyntaxError: Identifier expected. */ +/* @@? 16:31 Error TypeError: Invalid type reference. */ -- Gitee From 4f3f775610c64331a55baca40b08a9e9829e2911 Mon Sep 17 00:00:00 2001 From: zmw Date: Sat, 5 Jul 2025 12:03:02 +0800 Subject: [PATCH 044/107] Fix get set type crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK672 Description: Fix get set type crash Signed-off-by: zmw --- ets2panda/checker/ets/typeCheckingHelpers.cpp | 5 +++++ .../compiler/ets/set_init_without_param.ets | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/set_init_without_param.ets diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 82bbbc5041..aae078c4f6 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -474,6 +474,11 @@ Type *ETSChecker::GetTypeOfSetterGetter(varbinder::Variable *const var) return propType->FindGetter()->ReturnType(); } + if (propType->FindSetter()->Params().empty()) { + var->SetTsType(GlobalTypeError()); + return GlobalTypeError(); + } + return propType->FindSetter()->Params()[0]->TsType(); } diff --git a/ets2panda/test/ast/compiler/ets/set_init_without_param.ets b/ets2panda/test/ast/compiler/ets/set_init_without_param.ets new file mode 100644 index 0000000000..50710b371e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/set_init_without_param.ets @@ -0,0 +1,22 @@ +/* + * 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. + */ + +set a '1;' + +/* @@? 16:1 Error SyntaxError: Extension Setter can only have 2 parameters. */ +/* @@? 16:5 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 16:7 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 22:77 Error SyntaxError: Expected ')', got 'end of stream'. */ +/* @@? 22:77 Error SyntaxError: Extension Accessor must have a receiver. */ \ No newline at end of file -- Gitee From 23807b6bafeb5ffc583774a43381260ae837f4ee Mon Sep 17 00:00:00 2001 From: turgutbababalim Date: Fri, 2 May 2025 13:35:41 +0300 Subject: [PATCH 045/107] Double support for enum Issue: IC5PP6 Description: Added double type support and type annotation to enums Signed-off-by: turgutbababalim --- .../compiler/lowering/ets/enumLowering.cpp | 239 ++++++++++++++---- .../compiler/lowering/ets/enumLowering.h | 11 +- ets2panda/ir/ts/tsEnumDeclaration.h | 25 ++ ets2panda/parser/ETSparserEnums.cpp | 41 ++- ets2panda/test/ast/parser/ets/enum27.ets | 4 +- ets2panda/test/ast/parser/ets/enum33.ets | 19 ++ ets2panda/test/ast/parser/ets/enum34.ets | 22 ++ .../test/ast/parser/ets/enumAnnotation.ets | 19 ++ .../test/ast/parser/ets/enumAnnotation2.ets | 19 ++ .../test/ast/parser/ets/enumAnnotation3.ets | 22 ++ .../test/ast/parser/ets/enumAnnotation4.ets | 22 ++ .../test/ast/parser/ets/enumAnnotation5.ets | 23 ++ .../test/ast/parser/ets/enumAnnotation6.ets | 22 ++ .../test/ast/parser/ets/enumAnnotation7.ets | 23 ++ .../annotation_tests/EnumAnnotationAlias.ets | 24 ++ .../annotation_tests/EnumAnnotationAlias2.ets | 24 ++ ets2panda/test/unit/sizeof_node_test.cpp | 1 + ets2panda/util/diagnostic/syntax.yaml | 6 +- 18 files changed, 503 insertions(+), 63 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/enum33.ets create mode 100644 ets2panda/test/ast/parser/ets/enum34.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation2.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation3.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation4.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation5.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation6.ets create mode 100644 ets2panda/test/ast/parser/ets/enumAnnotation7.ets create mode 100644 ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias.ets create mode 100644 ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias2.ets diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 3d5b82941f..c7ee34884c 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -14,6 +14,8 @@ */ #include "enumLowering.h" +#include +#include #include "checker/ETSchecker.h" #include "checker/types/ets/etsEnumType.h" @@ -74,13 +76,13 @@ void EnumLoweringPhase::LogError(const diagnostic::DiagnosticKind &diagnostic, context_->diagnosticEngine->LogDiagnostic(diagnostic, diagnosticParams, pos); } -template +template bool EnumLoweringPhase::CheckEnumMemberType(const ArenaVector &enumMembers, bool &hasLoggedError, bool &hasLongLiteral) { for (auto *member : enumMembers) { auto *init = member->AsTSEnumMember()->Init(); - if constexpr (std::is_same_v) { + if constexpr (TYPE_NODE == EnumLoweringPhase::EnumType::INT) { if (!init->IsNumberLiteral() || !init->AsNumberLiteral()->Number().IsInteger()) { LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, init->Start()); hasLoggedError = true; @@ -98,7 +100,19 @@ bool EnumLoweringPhase::CheckEnumMemberType(const ArenaVector &en LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, init->Start()); hasLoggedError = true; } - } else if constexpr (std::is_same_v) { + } else if constexpr (TYPE_NODE == EnumLoweringPhase::EnumType::DOUBLE) { + if (!init->IsNumberLiteral() || + !(init->AsNumberLiteral()->Number().IsDouble() || init->AsNumberLiteral()->Number().IsFloat())) { + LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, init->Start()); + hasLoggedError = true; + + continue; + } + if (member->AsTSEnumMember()->IsGenerated()) { + LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, init->Start()); + hasLoggedError = true; + } + } else if constexpr (TYPE_NODE == EnumLoweringPhase::EnumType::STRING) { if (!init->IsStringLiteral()) { LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, init->Start()); hasLoggedError = true; @@ -108,7 +122,8 @@ bool EnumLoweringPhase::CheckEnumMemberType(const ArenaVector &en hasLoggedError = true; } } else { - static_assert(std::is_same_v, "Unsupported TypeNode in CheckEnumMemberType."); + static_assert(TYPE_NODE == + EnumLoweringPhase::EnumType::NOT_SPECIFIED); // Unsupported TypeNode in CheckEnumMemberType. } } return !hasLoggedError; @@ -157,6 +172,42 @@ template return arrayIdent; } +ir::Expression *EnumLoweringPhase::CheckEnumTypeForItemFields(EnumType enumType, ir::TSEnumMember *const member) +{ + ir::Expression *valueArgument = nullptr; + + switch (enumType) { + case EnumType::INT: { + auto enumFieldValue = + member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue(); + valueArgument = AllocNode(lexer::Number(enumFieldValue)); + break; + } + case EnumType::LONG: { + auto enumFieldValue = + member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue(); + valueArgument = AllocNode(lexer::Number(enumFieldValue)); + break; + } + case EnumType::DOUBLE: { + auto enumFieldValue = member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue(); + valueArgument = AllocNode(lexer::Number(enumFieldValue)); + break; + } + case EnumType::STRING: { + auto enumFieldValue = member->AsTSEnumMember()->Init()->AsStringLiteral()->Str(); + valueArgument = AllocNode(enumFieldValue); + break; + } + case EnumType::NOT_SPECIFIED: { + LogError(diagnostic::ENUM_INVALID_INIT, {}, member->AsTSEnumMember()->Init()->Start()); + break; + } + } + + return valueArgument; +} + void EnumLoweringPhase::CreateEnumItemFields(const ir::TSEnumDeclaration *const enumDecl, ir::ClassDefinition *const enumClass, EnumType enumType) { @@ -172,26 +223,8 @@ void EnumLoweringPhase::CreateEnumItemFields(const ir::TSEnumDeclaration *const ArenaVector newExprArgs(Allocator()->Adapter()); newExprArgs.push_back(ordinalLiteral); - ir::Expression *valueArgument = nullptr; - switch (enumType) { - case EnumType::INT: { - auto enumFieldValue = - member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue(); - valueArgument = AllocNode(lexer::Number(enumFieldValue)); - break; - } - case EnumType::LONG: { - auto enumFieldValue = - member->AsTSEnumMember()->Init()->AsNumberLiteral()->Number().GetValue(); - valueArgument = AllocNode(lexer::Number(enumFieldValue)); - break; - } - case EnumType::STRING: { - auto enumFieldValue = member->AsTSEnumMember()->Init()->AsStringLiteral()->Str(); - valueArgument = AllocNode(enumFieldValue); - break; - } - } + ir::Expression *valueArgument = CheckEnumTypeForItemFields(enumType, member); + newExprArgs.push_back(valueArgument); auto enumTypeAnnotation1 = enumTypeAnnotation->Clone(Allocator(), nullptr); @@ -238,6 +271,9 @@ static ir::TypeNode *CreateType(public_lib::Context *ctx, EnumLoweringPhase::Enu case EnumLoweringPhase::EnumType::LONG: { return ctx->AllocNode(ir::PrimitiveType::LONG, ctx->Allocator()); } + case EnumLoweringPhase::EnumType::DOUBLE: { + return ctx->AllocNode(ir::PrimitiveType::DOUBLE, ctx->Allocator()); + } case EnumLoweringPhase::EnumType::STRING: { return MakeTypeReference(ctx, EnumLoweringPhase::STRING_REFERENCE_TYPE); } @@ -489,6 +525,45 @@ ir::ClassDeclaration *EnumLoweringPhase::CreateEnumIntClassFromEnumDeclaration(i return enumClassDecl; } +template +ir::ClassDeclaration *EnumLoweringPhase::CreateEnumFloatClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl, + const DeclarationFlags flags) +{ + EnumType enumType = EnumType::DOUBLE; + + auto *const enumClassDecl = CreateClass(enumDecl, flags, enumType); + auto *const enumClass = enumClassDecl->Definition(); + + CreateEnumItemFields(enumDecl, enumClass, enumType); + auto *const namesArrayIdent = CreateEnumNamesArray(enumDecl, enumClass); + auto *const valuesArrayIdent = CreateEnumValuesArray(enumDecl, enumClass); + auto *const stringValuesArrayIdent = CreateEnumStringValuesArray(enumDecl, enumClass); + auto *const itemsArrayIdent = CreateEnumItemsArray(enumDecl, enumClass); + + CreateEnumGetNameMethod(enumDecl, enumClass, namesArrayIdent); + + CreateEnumGetValueOfMethod(enumDecl, enumClass, namesArrayIdent, itemsArrayIdent); + + CreateEnumFromValueMethod(enumDecl, enumClass, valuesArrayIdent, itemsArrayIdent, TYPE); + + CreateEnumValueOfMethod(enumDecl, enumClass, valuesArrayIdent, TYPE); + + CreateEnumToStringMethod(enumDecl, enumClass, stringValuesArrayIdent); + + CreateEnumValuesMethod(enumDecl, enumClass, itemsArrayIdent); + + CreateEnumGetOrdinalMethod(enumDecl, enumClass); + + CreateEnumDollarGetMethod(enumDecl, enumClass); + + SetDefaultPositionInUnfilledClassNodes(enumClassDecl, enumDecl); + + enumClassDecl->SetParent(enumDecl->Parent()); + ProcessEnumClassDeclaration(enumDecl, flags, enumClassDecl); + + return enumClassDecl; +} + ir::ClassDeclaration *EnumLoweringPhase::CreateEnumStringClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl, const DeclarationFlags flags) { @@ -533,6 +608,80 @@ static EnumLoweringPhase::DeclarationFlags GetDeclFlags(ir::TSEnumDeclaration *c enumDecl->Parent()->AsClassDefinition()->IsNamespaceTransformed()}; } +checker::AstNodePtr EnumLoweringPhase::TransformAnnotedEnumChildrenRecursively(checker::AstNodePtr &ast) +{ + auto *enumDecl = ast->AsTSEnumDeclaration(); + auto const flags = GetDeclFlags(enumDecl); + if (!flags.IsValid() || enumDecl->Members().empty()) { + return ast; + } + + bool hasLoggedError = false; + bool hasLongLiteral = false; + auto *const itemInit = enumDecl->Members().front()->AsTSEnumMember()->Init(); + ir::TypeNode *typeAnnotation = enumDecl->TypeNodes(); + + ir::PrimitiveType primitiveType = typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType(); + if ((primitiveType == ir::PrimitiveType::INT || primitiveType == ir::PrimitiveType::LONG) && + CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral)) { + auto res = hasLongLiteral ? CreateEnumIntClassFromEnumDeclaration(enumDecl, flags) + : CreateEnumIntClassFromEnumDeclaration(enumDecl, flags); + return res; + } + + if ((primitiveType == ir::PrimitiveType::DOUBLE) && + CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral)) { + return CreateEnumFloatClassFromEnumDeclaration(enumDecl, flags); + } + + if (!hasLoggedError) { + LogError(diagnostic::UNSUPPORTED_ENUM_TYPE, {}, itemInit->Start()); + } + + return ast; +} + +checker::AstNodePtr EnumLoweringPhase::TransformEnumChildrenRecursively(checker::AstNodePtr &ast) +{ + auto *enumDecl = ast->AsTSEnumDeclaration(); + auto const flags = GetDeclFlags(enumDecl); + if (!flags.IsValid()) { + return ast; + } + + if (enumDecl->Members().empty()) { + return CreateEnumIntClassFromEnumDeclaration(enumDecl, flags); + } + + bool hasLoggedError = false; + bool hasLongLiteral = false; + auto *const itemInit = enumDecl->Members().front()->AsTSEnumMember()->Init(); + + if (itemInit->IsNumberLiteral() && + ((itemInit->AsNumberLiteral()->Number().IsInteger() || itemInit->AsNumberLiteral()->Number().IsLong()) && + CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral))) { + auto res = hasLongLiteral ? CreateEnumIntClassFromEnumDeclaration(enumDecl, flags) + : CreateEnumIntClassFromEnumDeclaration(enumDecl, flags); + return res; + } + if (itemInit->IsNumberLiteral() && + ((itemInit->AsNumberLiteral()->Number().IsDouble() || itemInit->AsNumberLiteral()->Number().IsFloat()) && + CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral))) { + return CreateEnumFloatClassFromEnumDeclaration(enumDecl, flags); + } + + if (itemInit->IsStringLiteral() && + CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral)) { + return CreateEnumStringClassFromEnumDeclaration(enumDecl, flags); + } + + if (!hasLoggedError) { + LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, itemInit->Start()); + } + + return ast; +} + bool EnumLoweringPhase::PerformForModule(public_lib::Context *ctx, parser::Program *program) { if (program->Extension() != ScriptExtension::ETS) { @@ -551,36 +700,13 @@ bool EnumLoweringPhase::PerformForModule(public_lib::Context *ctx, parser::Progr program->Ast()->TransformChildrenRecursively( [this](checker::AstNodePtr ast) -> checker::AstNodePtr { if (ast->IsTSEnumDeclaration()) { - auto *enumDecl = ast->AsTSEnumDeclaration(); - auto const flags = GetDeclFlags(enumDecl); - if (!flags.IsValid()) { - return ast; - } - if (enumDecl->Members().empty()) { - return CreateEnumIntClassFromEnumDeclaration(enumDecl, flags); - } - - bool hasLoggedError = false; - bool hasLongLiteral = false; - auto *const itemInit = enumDecl->Members().front()->AsTSEnumMember()->Init(); - - if (itemInit->IsNumberLiteral() && - CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral)) { - auto res = hasLongLiteral - ? CreateEnumIntClassFromEnumDeclaration(enumDecl, flags) - : CreateEnumIntClassFromEnumDeclaration(enumDecl, flags); - return res; - } - if (itemInit->IsStringLiteral() && - CheckEnumMemberType(enumDecl->Members(), hasLoggedError, hasLongLiteral)) { - return CreateEnumStringClassFromEnumDeclaration(enumDecl, flags); - } + ir::TSEnumDeclaration *enumDecl = ast->AsTSEnumDeclaration(); - if (!hasLoggedError) { - LogError(diagnostic::ERROR_ARKTS_NO_ENUM_MIXED_TYPES, {}, itemInit->Start()); + if (enumDecl->TypeNodes() != nullptr) { + return TransformAnnotedEnumChildrenRecursively(ast); } - return ast; + return TransformEnumChildrenRecursively(ast); } return ast; }, @@ -625,11 +751,16 @@ ir::Identifier *EnumLoweringPhase::CreateEnumStringValuesArray(const ir::TSEnumD if (init->IsStringLiteral()) { stringValue = init->AsStringLiteral()->Str(); } else { - auto str = std::to_string( - init->AsNumberLiteral()->Number().GetValue()); + std::string str {}; + if (init->AsNumberLiteral()->Number().IsInteger()) { + std::int64_t res = init->AsNumberLiteral()->Number().GetValue(); + str = std::to_string(res); + } else { + double res = init->AsNumberLiteral()->Number().GetValue(); + str = std::to_string(res); + } stringValue = util::UString(str, Allocator()).View(); } - auto *const enumValueStringLiteral = AllocNode(stringValue); return enumValueStringLiteral; }); diff --git a/ets2panda/compiler/lowering/ets/enumLowering.h b/ets2panda/compiler/lowering/ets/enumLowering.h index 3f9f804534..f95443c8ce 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.h +++ b/ets2panda/compiler/lowering/ets/enumLowering.h @@ -19,6 +19,7 @@ #include #include #include "compiler/lowering/phase.h" +#include "checker/ETSchecker.h" namespace ark::es2panda::compiler { @@ -37,7 +38,7 @@ public: static constexpr std::string_view ORDINAL_NAME {"#ordinal"}; static constexpr auto ORDINAL_TYPE {ir::PrimitiveType::INT}; - enum EnumType { INT = 0, LONG = 1, STRING = 2 }; + enum EnumType { NOT_SPECIFIED = 0, INT = 1, LONG = 2, DOUBLE = 3, STRING = 4 }; struct DeclarationFlags { // NOLINTBEGIN(misc-non-private-member-variables-in-classes) @@ -81,7 +82,7 @@ private: const lexer::SourcePosition &pos); // clang-format off - template + template bool CheckEnumMemberType(const ArenaVector &enumMembers, bool &hasLoggedError, bool &hasLongLiteral); // clang-format on @@ -100,6 +101,9 @@ private: template ir::ClassDeclaration *CreateEnumIntClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl, const DeclarationFlags flags); + template + ir::ClassDeclaration *CreateEnumFloatClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl, + const DeclarationFlags flags); ir::ClassDeclaration *CreateEnumStringClassFromEnumDeclaration(ir::TSEnumDeclaration *const enumDecl, const DeclarationFlags flags); static void AppendParentNames(util::UString &qualifiedName, const ir::AstNode *const node); @@ -133,6 +137,9 @@ private: void CreateEnumDollarGetMethod(ir::TSEnumDeclaration const *const enumDecl, ir::ClassDefinition *const enumClass); void SetDefaultPositionInUnfilledClassNodes(const ir::ClassDeclaration *enumClassDecl, ir::TSEnumDeclaration const *const enumDecl); + ir::Expression *CheckEnumTypeForItemFields(EnumType enumType, ir::TSEnumMember *const member); + checker::AstNodePtr TransformEnumChildrenRecursively(checker::AstNodePtr &ast); + checker::AstNodePtr TransformAnnotedEnumChildrenRecursively(checker::AstNodePtr &ast); ArenaAllocator *Allocator(); template diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index 87bb7c13fd..5d3cb3dad2 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -43,6 +43,24 @@ public: : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), decorators_(allocator->Adapter()), key_(key), + typeNode_(nullptr), + members_(std::move(members)), + isConst_(flags.isConst) + { + if (flags.isStatic) { + AddModifier(ModifierFlags::STATIC); + } + if (flags.isDeclare) { + AddModifier(ModifierFlags::DECLARE); + } + } + + explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector &&members, + ConstructorFlags &&flags, ir::TypeNode *typeNode) + : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), + decorators_(allocator->Adapter()), + key_(key), + typeNode_(typeNode), members_(std::move(members)), isConst_(flags.isConst) { @@ -60,6 +78,7 @@ public: : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), decorators_(allocator->Adapter()), key_(key), + typeNode_(nullptr), members_(std::move(members)), isConst_(flags.isConst) { @@ -102,6 +121,11 @@ public: return GetHistoryNodeAs()->key_; } + TypeNode *TypeNodes() + { + return typeNode_; + } + Identifier *Key() { return GetHistoryNodeAs()->key_; @@ -184,6 +208,7 @@ private: varbinder::LocalScope *scope_ {nullptr}; ArenaVector decorators_; Identifier *key_; + ir::TypeNode *typeNode_; ArenaVector members_; util::StringView internalName_; ir::ClassDefinition *boxedClass_ {nullptr}; diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index c4f6989c72..4e6b8d9361 100644 --- a/ets2panda/parser/ETSparserEnums.cpp +++ b/ets2panda/parser/ETSparserEnums.cpp @@ -154,9 +154,32 @@ ir::Statement *ETSParser::ParsePotentialConstEnum(VariableParsingFlags flags) ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, const lexer::SourcePosition &enumStart, const bool isConst, const bool isStatic) { - if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE) { + if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_BRACE && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_BRACE); } + ir::TypeNode *typeAnnotation = nullptr; + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COLON) { + Lexer()->NextToken(); // eat ':' + TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR; + typeAnnotation = ParseTypeAnnotation(&options); + + // According to a comment on ETSparser.cpp:1598, compiler can't process ": string" correctly. + // ParseTypeAnnotation reads ": string" as literal so it's not supported here for now. + auto startPos = Lexer()->GetToken().Start(); + if (!typeAnnotation->IsETSPrimitiveType()) { + LogError(diagnostic::UNSUPPORTED_ENUM_TYPE, {}, startPos); + typeAnnotation = nullptr; + } else { + ir::PrimitiveType primitiveType = typeAnnotation->AsETSPrimitiveType()->GetPrimitiveType(); + if (primitiveType != ir::PrimitiveType::INT && primitiveType != ir::PrimitiveType::LONG && + primitiveType != ir::PrimitiveType::DOUBLE) { + // Issue: #26024 Numeric support for enum + LogError(diagnostic::UNSUPPORTED_ENUM_TYPE, {}, startPos); + typeAnnotation = nullptr; + } + } + } Lexer()->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); // eat '{' @@ -164,10 +187,20 @@ ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, co lexer::SourcePosition enumEnd = ParseEnumMember(members); - auto *const enumDeclaration = AllocNode( - Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}); + ir::TSEnumDeclaration *enumDeclaration; + + if (typeAnnotation == nullptr) { + enumDeclaration = AllocNode( + Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}); + } else { + enumDeclaration = AllocNode( + Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, typeAnnotation); + } + ES2PANDA_ASSERT(enumDeclaration != nullptr); + if (InAmbientContext()) { enumDeclaration->AddModifier(ir::ModifierFlags::DECLARE); } diff --git a/ets2panda/test/ast/parser/ets/enum27.ets b/ets2panda/test/ast/parser/ets/enum27.ets index f55d7a45a7..1e38fdc9cc 100644 --- a/ets2panda/test/ast/parser/ets/enum27.ets +++ b/ets2panda/test/ast/parser/ets/enum27.ets @@ -22,6 +22,6 @@ enum Date { Day = /* @@ label1 */Date.now() } -/* @@@ label Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ -/* @@@ label1 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ + /* @@@ label2 Error TypeError: Class 'Date' is already defined with different type. */ +/* @@@ label1 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ diff --git a/ets2panda/test/ast/parser/ets/enum33.ets b/ets2panda/test/ast/parser/ets/enum33.ets new file mode 100644 index 0000000000..4de3700721 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enum33.ets @@ -0,0 +1,19 @@ +/* + * 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 Percentage { + A = 0.45, + B = 0.55 +} diff --git a/ets2panda/test/ast/parser/ets/enum34.ets b/ets2panda/test/ast/parser/ets/enum34.ets new file mode 100644 index 0000000000..9fcdc33582 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enum34.ets @@ -0,0 +1,22 @@ +/* + * 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 Fraction { + A = 1, + B = 0.1 +} + + +/* @@? 18:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation.ets b/ets2panda/test/ast/parser/ets/enumAnnotation.ets new file mode 100644 index 0000000000..625a12d886 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation.ets @@ -0,0 +1,19 @@ +/* + * 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 Fraction: int { + A = 1, + B = 1 +} diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation2.ets b/ets2panda/test/ast/parser/ets/enumAnnotation2.ets new file mode 100644 index 0000000000..d790c608a3 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation2.ets @@ -0,0 +1,19 @@ +/* + * 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 Fraction: double { + A = 1.2, + B = 3.1 +} diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation3.ets b/ets2panda/test/ast/parser/ets/enumAnnotation3.ets new file mode 100644 index 0000000000..17fc47a361 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation3.ets @@ -0,0 +1,22 @@ +/* + * 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 Fraction: string { + A = "A", + B = "B" +} + + +/* @@? 16:23 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation4.ets b/ets2panda/test/ast/parser/ets/enumAnnotation4.ets new file mode 100644 index 0000000000..2816b123bb --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation4.ets @@ -0,0 +1,22 @@ +/* + * 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 Fraction: customInt { + A = 1, + B = 2 +} + + +/* @@? 16:26 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation5.ets b/ets2panda/test/ast/parser/ets/enumAnnotation5.ets new file mode 100644 index 0000000000..64ff1a3635 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation5.ets @@ -0,0 +1,23 @@ +/* + * 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 Fraction: int { + A = "A", + B = "B" +} + + +/* @@? 17:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ +/* @@? 18:9 Error TypeError: Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation6.ets b/ets2panda/test/ast/parser/ets/enumAnnotation6.ets new file mode 100644 index 0000000000..b52526a67f --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation6.ets @@ -0,0 +1,22 @@ +/* + * 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 Fraction: byte { + A = 1, + B = 2 +} + + +/* @@? 16:21 Error SyntaxError: Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations. */ diff --git a/ets2panda/test/ast/parser/ets/enumAnnotation7.ets b/ets2panda/test/ast/parser/ets/enumAnnotation7.ets new file mode 100644 index 0000000000..05c4208c2c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/enumAnnotation7.ets @@ -0,0 +1,23 @@ +/* + * 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 E: double{ + A = 1.1, + B = 1.2 + 1.3, + C = B, + D = C + 1.5, + E = D - 2.5, + F = D * C, +} \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias.ets b/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias.ets new file mode 100644 index 0000000000..2f4b6aafbe --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias.ets @@ -0,0 +1,24 @@ +/* + * 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 Status { + Pending, + InProgress, + Complete +} + +type StatusType = Status; + +let current: StatusType = Status.InProgress; diff --git a/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias2.ets b/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias2.ets new file mode 100644 index 0000000000..495bfaeb9e --- /dev/null +++ b/ets2panda/test/runtime/ets/annotation_tests/EnumAnnotationAlias2.ets @@ -0,0 +1,24 @@ +/* + * 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 Status: int { + Pending = 1, + InProgress = 2, + Complete = 3 +} + +type StatusType = Status; + +let current: StatusType = Status.InProgress; diff --git a/ets2panda/test/unit/sizeof_node_test.cpp b/ets2panda/test/unit/sizeof_node_test.cpp index 5f150147f1..8cf6d3d293 100644 --- a/ets2panda/test/unit/sizeof_node_test.cpp +++ b/ets2panda/test/unit/sizeof_node_test.cpp @@ -347,6 +347,7 @@ size_t SizeOfNodeTest::SizeOf() sizeof(node->members_) + sizeof(node->internalName_) + sizeof(node->boxedClass_) + + sizeof(node->typeNode_) + Align(sizeof(node->isConst_)); // clang-format on } diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 2034b92c73..87fa64579b 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1310,4 +1310,8 @@ syntax: - name: MORE_INDEXER id: 326 - message: "Only one index signature can exist in a class" \ No newline at end of file + message: "Only one index signature can exist in a class" + +- name: UNSUPPORTED_ENUM_TYPE + id: 327 + message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations." -- Gitee From 0fb63197c2b16b30dbbc2b2a222a61bf00a43a9f Mon Sep 17 00:00:00 2001 From: Daniel Kofanov Date: Sat, 5 Jul 2025 01:22:11 +0800 Subject: [PATCH 046/107] [ETS] Fix const-folding corner cases Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK522 Change-Id: I81416b0511079539ae20978321934f2afa325e5e Signed-off-by: Daniel Kofanov --- .../ets/constantExpressionLowering.cpp | 4 +-- .../ets/constantExpressionLowering.ets | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 8aa9606232..7307d9f8c9 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1097,7 +1097,7 @@ static ir::AstNode *FoldUnaryExpression(const ir::UnaryExpression *unary, public } auto lit = unary->Argument()->AsLiteral(); - if (lit->IsNumberLiteral() || lit->IsCharLiteral() || lit->IsBooleanLiteral()) { + if (lit->IsNumberLiteral() || lit->IsCharLiteral()) { return FoldUnaryNumericConstant(unary, context->allocator); } @@ -1127,7 +1127,7 @@ static ir::AstNode *FoldTemplateLiteral(ir::TemplateLiteral *expr, ArenaAllocato auto quasis = expr->Quasis(); auto expressions = expr->Expressions(); - if (!quasis[0]->Raw().Empty()) { + if (!quasis.empty() && !quasis[0]->Raw().Empty()) { result.Append(quasis[0]->Cooked()); } diff --git a/ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets b/ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets new file mode 100644 index 0000000000..fa6ab227a5 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/constantExpressionLowering.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ + +// 1. +const tmpl = `` + +// 2. +const flag = true +const a = +(flag) +const b = -(flag) +const c = ~(flag) + +/* @@? 21:11 Error TypeError: Wrong operand type for unary expression */ +/* @@? 22:11 Error TypeError: Wrong operand type for unary expression */ +/* @@? 23:11 Error TypeError: Wrong operand type for unary expression */ -- Gitee From 151731d941eb968546ef8f21ba1d96dbb0b00214 Mon Sep 17 00:00:00 2001 From: a00917162 Date: Sun, 6 Jul 2025 17:25:49 +0300 Subject: [PATCH 047/107] Fix nullptr in async function expression Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKAUD Testing: all CI tests passed. Results are availible in gg watcher. Signed-off-by: Akmaev Aleksey --- ets2panda/parser/ETSparserExpressions.cpp | 5 ++ .../ets/async-function-expression1.ets | 54 +++++++++++++++ .../ets/async-function-expression2.ets | 66 +++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/async-function-expression1.ets create mode 100644 ets2panda/test/ast/compiler/ets/async-function-expression2.ets diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index bff2cbec61..8337da604a 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -688,6 +688,11 @@ ir::Expression *ETSParser::ParseNewExpression() ir::Expression *ETSParser::ParseAsyncExpression() { Lexer()->NextToken(); // eat 'async' + if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_FUNCTION) { + LogError(diagnostic::FUNC_EXPR); + ParseFunctionDeclaration(true, ir::ModifierFlags::NONE); + return AllocBrokenExpression(Lexer()->GetToken().Loc()); + } if (Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || !IsArrowFunctionExpressionStart()) { LogExpectedToken(lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); diff --git a/ets2panda/test/ast/compiler/ets/async-function-expression1.ets b/ets2panda/test/ast/compiler/ets/async-function-expression1.ets new file mode 100644 index 0000000000..de02a74245 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/async-function-expression1.ets @@ -0,0 +1,54 @@ +/* + * 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. + */ + +function relationalStoreCustomDirTest() { + it(async function () {}) + + it(async function () { + let storestore = null; + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) + + it(async function () { + const STORE_CONFIG = { + name: "", + securityLevel: data_Rdb.SecurityLevel.S1, + customDir: "" + } + let storestore = await data_Rdb.getRdbStore(context, STORE_CONFIG); + await storestore.executeSql(CREATE_TABLE_TEST, null); + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) +} +/* @@? 17:5 Error TypeError: Unresolved reference it */ +/* @@? 17:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:5 Error TypeError: This expression is not callable. */ +/* @@? 19:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 31:5 Error TypeError: This expression is not callable. */ +/* @@? 31:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ diff --git a/ets2panda/test/ast/compiler/ets/async-function-expression2.ets b/ets2panda/test/ast/compiler/ets/async-function-expression2.ets new file mode 100644 index 0000000000..c4fef79dcf --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/async-function-expression2.ets @@ -0,0 +1,66 @@ +/* + * 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. + */ + +function relationalStoreCustomDirTest() { + it(async function function() {}) + + it(async function function() { + let storestore = null; + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) + + it(async function function() { + const STORE_CONFIG = { + name: "", + securityLevel: data_Rdb.SecurityLevel.S1, + customDir: "" + } + let storestore = await data_Rdb.getRdbStore(context, STORE_CONFIG); + await storestore.executeSql(CREATE_TABLE_TEST, null); + let u8 = new Uint8Array([1, 2, 3]); + const valueBucket = { + "name": "", + "age": 18, + "salary": 100.5, + "blobType": u8, + } + let ret = await storestore.insert("test", valueBucket); + }) +} +/* @@? 17:5 Error TypeError: Unresolved reference it */ +/* @@? 17:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 17:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 17:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 17:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:5 Error TypeError: This expression is not callable. */ +/* @@? 19:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 19:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 19:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 19:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 19:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 31:5 Error TypeError: This expression is not callable. */ +/* @@? 31:14 Error SyntaxError: Function expressions are not supported, use arrow functions instead */ +/* @@? 31:23 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 31:31 Error SyntaxError: Unexpected token, expected an identifier. */ +/* @@? 31:31 Error SyntaxError: Parameter declaration should have an explicit type annotation. */ +/* @@? 31:31 Error SyntaxError: Unexpected token, expected ',' or ')'. */ -- Gitee From b0fad07d2fa99e3ea82a59dfab83bebf981f1e99 Mon Sep 17 00:00:00 2001 From: lirismankarina Date: Mon, 30 Jun 2025 20:27:21 +0300 Subject: [PATCH 048/107] Fix codecheck in frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: [新需求]: dev branch codecheck fix https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICIYU3 Description: new part of codecheck for frontend Reason: need dommon code style Tests: all tests passed Signed-off-by: lirismankarina Signed-off-by: Zhelyapov Aleksey --- .../lowering/ets/declareOverloadLowering.cpp | 2 + ...defaultParametersInConstructorLowering.cpp | 10 +++- .../compiler/lowering/ets/enumLowering.cpp | 7 +++ .../lowering/ets/exportAnonymousConst.cpp | 1 + .../lowering/ets/expressionLambdaLowering.cpp | 1 + .../lowering/ets/genericBridgesLowering.cpp | 3 + .../ets/interfaceObjectLiteralLowering.cpp | 8 ++- .../ets/interfacePropertyDeclarations.cpp | 1 + .../compiler/lowering/ets/lambdaLowering.cpp | 56 +++++++++++++------ .../lowering/ets/lateInitialization.cpp | 2 + ets2panda/ir/ets/etsClassLiteral.cpp | 1 + ets2panda/ir/ets/etsFunctionType.cpp | 1 + ets2panda/ir/ets/etsKeyofType.cpp | 2 + ets2panda/ir/ets/etsNeverType.cpp | 1 + .../ir/ets/etsNewArrayInstanceExpression.cpp | 1 + .../ir/ets/etsNewClassInstanceExpression.cpp | 1 + .../etsNewMultiDimArrayInstanceExpression.cpp | 1 + ets2panda/ir/ets/etsNonNullishTypeNode.cpp | 1 + ets2panda/ir/ets/etsNullishTypes.cpp | 2 + ets2panda/ir/ets/etsPackageDeclaration.cpp | 1 + ets2panda/ir/ets/etsParameterExpression.cpp | 1 + ets2panda/ir/ets/etsParameterExpression.h | 1 + ets2panda/ir/ets/etsPrimitiveType.cpp | 1 + ets2panda/ir/ets/etsStringLiteralType.cpp | 1 + ets2panda/ir/ets/etsTuple.cpp | 2 + ets2panda/ir/ets/etsTypeReferencePart.cpp | 1 + ets2panda/ir/ets/etsUnionType.cpp | 1 + ets2panda/ir/expressions/arrayExpression.cpp | 3 + .../expressions/arrowFunctionExpression.cpp | 3 + .../ir/expressions/assignmentExpression.cpp | 1 + ets2panda/ir/expressions/awaitExpression.cpp | 1 + ets2panda/ir/expressions/binaryExpression.cpp | 1 + ets2panda/ir/expressions/binaryExpression.h | 2 + ets2panda/ir/expressions/blockExpression.cpp | 1 + 34 files changed, 104 insertions(+), 19 deletions(-) diff --git a/ets2panda/compiler/lowering/ets/declareOverloadLowering.cpp b/ets2panda/compiler/lowering/ets/declareOverloadLowering.cpp index 434636afec..c65dccccc6 100644 --- a/ets2panda/compiler/lowering/ets/declareOverloadLowering.cpp +++ b/ets2panda/compiler/lowering/ets/declareOverloadLowering.cpp @@ -49,6 +49,7 @@ void GenerateOverloadHelperParams(public_lib::Context *ctx, uint32_t minArg, siz spread->SetTsType(arr); restIdent->SetTsType(arr); auto *param = ctx->AllocNode(spread, nullptr, allocator); + ES2PANDA_ASSERT(param); restIdent->SetParent(spread); typeAnnotation->SetParent(spread); @@ -84,6 +85,7 @@ void BuildOverloadHelperFunction(public_lib::Context *ctx, ir::MethodDefinition method->Modifiers(), allocator, false); method->AddOverload(helperOverload); + ES2PANDA_ASSERT(helperOverload->Function()); helperOverload->Function()->ClearFlag((ir::ScriptFunctionFlags::OVERLOAD)); helperOverload->SetParent(method); diff --git a/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp index 2c0f2d3203..3b7466ef9f 100644 --- a/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParametersInConstructorLowering.cpp @@ -63,6 +63,7 @@ static bool HasDefaultParameters(const ir::ScriptFunction *function, util::Diagn static ir::TSTypeParameterDeclaration *CreateParameterDeclaraion(ir::MethodDefinition *method, public_lib::Context *ctx) { auto const allocator = ctx->allocator; + ES2PANDA_ASSERT(method->Function()); if (method->Function()->TypeParams() == nullptr || method->Function()->TypeParams()->Params().empty()) { return nullptr; } @@ -90,6 +91,7 @@ static ir::FunctionSignature CreateFunctionSignature(ir::MethodDefinition *metho auto const allocator = ctx->allocator; ir::TSTypeParameterDeclaration *typeParamDecl = CreateParameterDeclaraion(method, ctx); + ES2PANDA_ASSERT(method->Function()); auto *returnTypeAnnotation = method->Function()->ReturnTypeAnnotation() != nullptr ? method->Function()->ReturnTypeAnnotation()->Clone(allocator, nullptr)->AsTypeNode() @@ -103,6 +105,7 @@ static ir::TSTypeParameterInstantiation *CreateTypeParameterInstantiation(ir::Me { auto const allocator = ctx->allocator; + ES2PANDA_ASSERT(method->Function()); if (method->Function()->TypeParams() == nullptr || method->Function()->TypeParams()->Params().empty()) { return nullptr; } @@ -130,6 +133,7 @@ static ir::BlockStatement *CreateFunctionBody(ir::MethodDefinition *method, publ { auto const allocator = ctx->allocator; ArenaVector funcStatements(allocator->Adapter()); + ES2PANDA_ASSERT(method->Id()); auto *const callee = util::NodeAllocator::ForceSetParent(allocator, method->Id()->Name(), allocator); @@ -163,6 +167,7 @@ static ir::FunctionExpression *CreateFunctionExpression(ir::MethodDefinition *me allocator, allocator, ir::ScriptFunction::ScriptFunctionData { body, std::move(signature), method->Function()->Flags(), {}, method->Function()->Language()}); + ES2PANDA_ASSERT(method->Function()); funcNode->AddModifier(method->Function()->Modifiers()); funcNode->SetRange({startLoc, endLoc}); @@ -184,6 +189,7 @@ static void CreateFunctionOverload(ir::MethodDefinition *method, ArenaVectorFunction()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD | ir::ScriptFunctionFlags::SYNTHETIC); overloadMethod->SetRange(funcExpression->Range()); + ES2PANDA_ASSERT(overloadMethod->Function()); if (!method->IsDeclare() && method->Parent()->IsTSInterfaceBody()) { overloadMethod->Function()->Body()->AsBlockStatement()->ClearStatements(); } @@ -195,6 +201,7 @@ static void CreateFunctionOverload(ir::MethodDefinition *method, ArenaVectorallocator; for (auto p : function->Params()) { @@ -227,6 +234,7 @@ static void ClearOptionalParameters(public_lib::Context *ctx, ir::ScriptFunction if (oldParam->IsOptional()) { param = util::NodeAllocator::ForceSetParent(allocator, oldParam->Ident(), false, allocator); + ES2PANDA_ASSERT(param); param->SetParent(function); } ES2PANDA_ASSERT(!param->AsETSParameterExpression()->IsOptional()); @@ -253,7 +261,7 @@ static void ProcessGlobalFunctionDefinition(ir::MethodDefinition *method, public for (size_t i = 0; i < params.size() - paramsToCut; ++i) { auto param = params[i]->AsETSParameterExpression(); callArgs.push_back(param->Ident()->CloneReference(allocator, nullptr)->AsIdentifier()); - + ES2PANDA_ASSERT(param->Ident()->Clone(allocator, nullptr)); functionParams.push_back(allocator->New( param->Ident()->Clone(allocator, nullptr)->AsIdentifier(), false, allocator)); } diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 3d5b82941f..5eedca78f3 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -39,6 +39,7 @@ namespace { [[nodiscard]] ir::Identifier *MakeParamRefIdent(public_lib::Context *ctx, ir::ETSParameterExpression *paramExpr) { auto *const refIdent = ctx->AllocNode(paramExpr->Ident()->Name(), ctx->Allocator()); + ES2PANDA_ASSERT(refIdent); refIdent->SetRange(paramExpr->Ident()->Range()); refIdent->SetVariable(paramExpr->Ident()->Variable()); return refIdent; @@ -418,13 +419,17 @@ void EnumLoweringPhase::ProcessEnumClassDeclaration(ir::TSEnumDeclaration *const auto *ident = enumClassDecl->Definition()->Ident(); if (flags.isLocal) { auto *scope = NearestScope(enumDecl->Parent()); + ES2PANDA_ASSERT(scope); auto localCtx = varbinder::LexicalScope::Enter(varbinder_, scope); + ES2PANDA_ASSERT(scope); scope->EraseBinding(ident->Name()); InitScopesPhaseETS::RunExternalNode(enumClassDecl, varbinder_); var = varbinder_->GetScope()->FindLocal(ident->Name(), varbinder::ResolveBindingOptions::ALL); } else if (flags.isTopLevel) { auto *scope = program_->GlobalClassScope(); + ES2PANDA_ASSERT(scope); auto localCtx = varbinder::LexicalScope::Enter(varbinder_, scope); + ES2PANDA_ASSERT(scope); scope->StaticDeclScope()->EraseBinding(ident->Name()); InitScopesPhaseETS::RunExternalNode(enumClassDecl, varbinder_); var = varbinder_->GetScope()->FindLocal(ident->Name(), varbinder::ResolveBindingOptions::ALL); @@ -796,11 +801,13 @@ ir::VariableDeclaration *CreateForLoopInitVariableDeclaration(public_lib::Contex static_assert(EnumLoweringPhase::ORDINAL_TYPE == ir::PrimitiveType::INT); auto *const init = ctx->AllocNode(lexer::Number((int32_t)0)); auto *const decl = ctx->AllocNode(ir::VariableDeclaratorFlag::LET, loopIdentifier, init); + ES2PANDA_ASSERT(loopIdentifier); loopIdentifier->SetParent(decl); ArenaVector decls(ctx->Allocator()->Adapter()); decls.push_back(decl); auto *const declaration = ctx->AllocNode( ir::VariableDeclaration::VariableDeclarationKind::LET, ctx->Allocator(), std::move(decls)); + ES2PANDA_ASSERT(decl); decl->SetParent(declaration); return declaration; } diff --git a/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp b/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp index d67d756dec..26a2f43910 100644 --- a/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp +++ b/ets2panda/compiler/lowering/ets/exportAnonymousConst.cpp @@ -110,6 +110,7 @@ static void HandleExportDefaultInExportNamedDecl(public_lib::Context *const ctx, exports.emplace_back(specifier); auto *exportDefaulNamedDecl = allocator->New( allocator, static_cast(nullptr), std::move(exports)); + ES2PANDA_ASSERT(exportDefaulNamedDecl); exportDefaulNamedDecl->AddModifier(ir::ModifierFlags::DEFAULT_EXPORT); exportDefaulNamedDeclarations.push_back(exportDefaulNamedDecl); continue; diff --git a/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp b/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp index 7d4112c7f6..e09b2b2af2 100644 --- a/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/expressionLambdaLowering.cpp @@ -37,6 +37,7 @@ static ir::AstNode *ConvertExpression(public_lib::Context *ctx, ir::ArrowFunctio auto *const block = ctx->AllocNode(allocator, std::move(statements)); + ES2PANDA_ASSERT(block); block->SetScope(scope); block->SetParent(function); diff --git a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp index 1e2d1d47ff..e74ea9ce95 100644 --- a/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp +++ b/ets2panda/compiler/lowering/ets/genericBridgesLowering.cpp @@ -80,12 +80,14 @@ void GenericBridgesPhase::AddGenericBridge(ir::ClassDefinition const *const clas { auto *parser = context_->parser->AsETSParser(); std::vector typeNodes {}; + ES2PANDA_ASSERT(baseSignature); typeNodes.reserve(2U * baseSignature->Params().size() + 2U); auto const sourceCode = CreateMethodDefinitionString(classDefinition, baseSignature, derivedFunction, typeNodes); auto *const bridgeMethod = parser->CreateFormattedClassMethodDefinition(sourceCode, typeNodes)->AsMethodDefinition(); + ES2PANDA_ASSERT(bridgeMethod); bridgeMethod->AddModifier(methodDefinition->Modifiers()); bridgeMethod->ClearModifier(ir::ModifierFlags::NATIVE | ir::ModifierFlags::ABSTRACT); bridgeMethod->AddAstNodeFlags(methodDefinition->GetAstNodeFlags()); @@ -147,6 +149,7 @@ void GenericBridgesPhase::ProcessScriptFunction(ir::ClassDefinition const *const // We are not interested in functions that either don't have type parameters at all // or have type parameters that are not modified in the derived class + ES2PANDA_ASSERT(baseFunction); auto const *baseSignature1 = baseFunction->Signature()->Substitute(relation, &substitutions.baseConstraints); if (baseSignature1 == baseFunction->Signature()) { return; diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 21e3981ab2..1e4f5046a9 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -93,6 +93,7 @@ static ir::MethodDefinition *CreateAnonClassFieldGetterSetter(public_lib::Contex { auto *const parser = ctx->parser->AsETSParser(); // Field type annotation + ES2PANDA_ASSERT(ifaceMethod->Function()); auto *fieldType = ifaceMethod->Function()->Signature()->ReturnType(); ES2PANDA_ASSERT(fieldType != nullptr); @@ -103,7 +104,7 @@ static ir::MethodDefinition *CreateAnonClassFieldGetterSetter(public_lib::Contex sourceCode << "public set @@I1 (anonParam:@@T2){" << std::endl; sourceCode << "this.@@I3 = anonParam" << std::endl; sourceCode << "}" << std::endl; - + ES2PANDA_ASSERT(ifaceMethod->Id()); return parser ->CreateFormattedClassMethodDefinition(sourceCode.str(), ifaceMethod->Id()->Name(), fieldType, anonClassFieldName) @@ -133,6 +134,7 @@ static void FillClassBody(public_lib::Context *ctx, ArenaVector * ES2PANDA_ASSERT(it->IsMethodDefinition()); auto *ifaceMethod = it->AsMethodDefinition(); + ES2PANDA_ASSERT(ifaceMethod->Function()); if (!ifaceMethod->Function()->IsGetter()) { continue; } @@ -203,6 +205,7 @@ static void AnnotateGeneratedAnonClass(checker::ETSChecker *checker, ir::ClassDe checker->ProgramAllocNode(Signatures::INTERFACE_OBJ_LITERAL, checker->ProgramAllocator()); annoId->SetAnnotationUsage(); auto *annoUsage = checker->ProgramAllocNode(annoId, checker->ProgramAllocator()); + ES2PANDA_ASSERT(annoUsage); annoUsage->AddModifier(ir::ModifierFlags::ANNOTATION_USAGE); annoUsage->SetParent(classDef); annoId->SetParent(annoUsage); @@ -256,6 +259,7 @@ static void GenerateAnonClassTypeFromInterface(public_lib::Context *ctx, ir::TSI // Class implements auto *classImplements = ctx->AllocNode( ctx->AllocNode(ifaceNode->TsType(), ctx->Allocator())); + ES2PANDA_ASSERT(classImplements); classImplements->SetParent(classDef); classDef->EmplaceImplements(classImplements); classType->RemoveObjectFlag(checker::ETSObjectFlags::RESOLVED_INTERFACES); @@ -336,6 +340,7 @@ static checker::Type *ProcessDeclNode(checker::ETSChecker *checker, checker::ETS continue; } + ES2PANDA_ASSERT(it->AsMethodDefinition()->Id()); checker->LogError(diagnostic::ABSTRACT_METH_IN_ABSTRACT_CLASS, {it->AsMethodDefinition()->Id()->Name()}, objExpr->Start()); return checker->GlobalTypeError(); @@ -390,6 +395,7 @@ static bool CheckInterfaceShouldGenerateAnonClass(ir::TSInterfaceDeclaration *in } ES2PANDA_ASSERT(it->IsMethodDefinition()); auto methodDef = it->AsMethodDefinition(); + ES2PANDA_ASSERT(methodDef->Function()); if (!methodDef->Function()->IsGetter() && !methodDef->Function()->IsSetter()) { return false; } diff --git a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp index b9aafa8736..2e5816e2e6 100644 --- a/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp +++ b/ets2panda/compiler/lowering/ets/interfacePropertyDeclarations.cpp @@ -192,6 +192,7 @@ static void AddOverload(ir::MethodDefinition *method, ir::MethodDefinition *over { method->AddOverload(overload); overload->SetParent(method); + ES2PANDA_ASSERT(overload->Function()); overload->Function()->AddFlag(ir::ScriptFunctionFlags::OVERLOAD); overload->Function()->Id()->SetVariable(variable); } diff --git a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp index ea7d21b1dd..f621292487 100644 --- a/ets2panda/compiler/lowering/ets/lambdaLowering.cpp +++ b/ets2panda/compiler/lowering/ets/lambdaLowering.cpp @@ -117,6 +117,7 @@ static std::pair CloneT auto *newTypeParamNode = util::NodeAllocator::ForceSetParent(allocator, newTypeParamId, nullptr, nullptr, allocator); auto *newTypeParam = allocator->New(); + ES2PANDA_ASSERT(newTypeParam); newTypeParam->SetDeclNode(newTypeParamNode); auto *newTypeParamDecl = allocator->New(newTypeParamId->Name()); @@ -160,6 +161,19 @@ static std::pair CloneT using ParamsAndVarMap = std::pair, ArenaMap>; +inline static varbinder::Variable *InitNewParameterVariable(varbinder::VarBinder *varBinder, + ir::ETSParameterExpression *param, + checker::Type *newParamType, + varbinder::ParamScope *paramScope) +{ + auto *var = varBinder->AddParamDecl(param); + var->SetTsType(newParamType); + var->SetScope(paramScope); + param->SetVariable(var); + param->SetTsType(newParamType); + return var; +} + ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, ir::ArrowFunctionExpression *lambda, ArenaSet const &captured, varbinder::ParamScope *paramScope, checker::Substitution *substitution) @@ -178,11 +192,7 @@ ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, ir::Arrow allocator, capturedVar->Name(), allocator->New(newType, allocator), allocator); auto param = util::NodeAllocator::ForceSetParent(allocator, newId, false, allocator); - auto *var = varBinder->AddParamDecl(param); - var->SetTsType(newType); - var->SetScope(paramScope); - param->SetVariable(var); - param->SetTsType(newType); + auto *var = InitNewParameterVariable(varBinder, param, newType, paramScope); resParams.push_back(param); varMap[capturedVar] = var; } @@ -191,16 +201,15 @@ ParamsAndVarMap CreateLambdaCalleeParameters(public_lib::Context *ctx, ir::Arrow auto *oldParamType = oldParam->AsETSParameterExpression()->Ident()->TsType(); auto *newParamType = oldParamType->Substitute(checker->Relation(), substitution); auto *newParam = oldParam->AsETSParameterExpression()->Clone(allocator, nullptr); + ES2PANDA_ASSERT(newParam); + if (newParam->IsOptional()) { newParam->SetOptional(false); newParamType = checker->CreateETSUnionType({newParamType, checker->GlobalETSUndefinedType()}); } + newParam->SetTypeAnnotation(allocator->New(newParamType, allocator)); - auto *var = varBinder->AddParamDecl(newParam); - var->SetTsType(newParamType); - var->SetScope(paramScope); - newParam->SetVariable(var); - newParam->SetTsType(newParamType); + auto *var = InitNewParameterVariable(varBinder, newParam, newParamType, paramScope); newParam->Ident()->SetTsType(newParamType); if (newParam->IsRestParameter()) { newParam->TypeAnnotation()->SetParent(newParam->Spread()); @@ -296,6 +305,7 @@ static ir::MethodDefinition *SetUpCalleeMethod(public_lib::Context *ctx, LambdaI var->AddFlag(varbinder::VariableFlags::METHOD); var->SetScope(scopeForMethod); func->Id()->SetVariable(var); + ES2PANDA_ASSERT(method->Id()); method->Id()->SetVariable(var); if (info->callReceiver != nullptr) { auto paramScopeCtx = varbinder::LexicalScope::Enter(varBinder, paramScope); @@ -342,9 +352,8 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar auto varMap = std::move(vMap); auto arrowReturnType = lambda->TsType()->AsETSFunctionType()->ArrowSignature()->ReturnType(); - auto *returnType = cmInfo->forcedReturnType != nullptr - ? cmInfo->forcedReturnType - : arrowReturnType->Substitute(checker->Relation(), &substitution); + auto *alternative = arrowReturnType->Substitute(checker->Relation(), &substitution); + auto *returnType = cmInfo->forcedReturnType != nullptr ? cmInfo->forcedReturnType : alternative; auto returnTypeAnnotation = allocator->New(returnType, allocator); auto funcFlags = ir::ScriptFunctionFlags::METHOD | cmInfo->auxFunctionFlags; @@ -360,6 +369,7 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar funcFlags, modifierFlags}); auto *funcScope = cmInfo->body == nullptr ? allocator->New(allocator, paramScope) : cmInfo->body->Scope()->AsFunctionScope(); + ES2PANDA_ASSERT(funcScope); funcScope->BindName(info->calleeClass->Definition()->TsType()->AsETSObjectType()->AssemblerName()); func->SetScope(funcScope); ProcessCalleeMethodBody(cmInfo->body, checker, paramScope, &substitution, varMap); @@ -379,9 +389,8 @@ static ir::MethodDefinition *CreateCalleeMethod(public_lib::Context *ctx, ir::Ar */ for (auto [ov, nv] : varMap) { ES2PANDA_ASSERT(ov->Name() == nv->Name()); - auto name = ov->Name(); - funcScope->EraseBinding(name); - funcScope->InsertBinding(name, nv); + funcScope->EraseBinding(ov->Name()); + funcScope->InsertBinding(ov->Name(), nv); } return SetUpCalleeMethod(ctx, info, cmInfo, func, scopeForMethod); @@ -503,6 +512,7 @@ static void CreateLambdaClassConstructor(public_lib::Context *ctx, ir::ClassDefi ir::ScriptFunction::ScriptFunctionData {body, ir::FunctionSignature(nullptr, std::move(params), nullptr), ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::IMPLICIT_SUPER_CALL_NEEDED}); + ES2PANDA_ASSERT(func); func->SetIdent(constructorId); auto *funcExpr = util::NodeAllocator::ForceSetParent(allocator, func); @@ -583,6 +593,7 @@ static ArenaVector CreateRestArgumentsArrayReall checker->MaybeBoxType(elementType), restParameterIndex, restParameterIndex); } + ES2PANDA_ASSERT(args); return ArenaVector(args->AsBlockStatement()->Statements()); } @@ -593,6 +604,7 @@ static void CreateInvokeMethodRestParameter(public_lib::Context *ctx, LambdaClas auto *checker = ctx->GetChecker()->AsETSChecker(); auto *restIdent = Gensym(allocator); + ES2PANDA_ASSERT(restIdent); lciInfo->restParameterIdentifier = restIdent->Name(); auto *spread = allocator->New(ir::AstNodeType::REST_ELEMENT, allocator, restIdent); auto *arr = lciInfo->lambdaSignature->RestVar()->TsType()->IsETSTupleType() @@ -773,6 +785,7 @@ static checker::ETSObjectType *FunctionTypeToLambdaProviderType(checker::ETSChec checker::Signature *signature) { if (signature->RestVar() != nullptr) { + ES2PANDA_ASSERT(checker->GlobalBuiltinLambdaType(signature->ArgCount(), true)); return checker->GlobalBuiltinLambdaType(signature->ArgCount(), true)->AsETSObjectType(); } // Note: FunctionN is not supported yet @@ -836,7 +849,7 @@ static ir::ClassDeclaration *CreateEmptyLambdaClassDeclaration(public_lib::Conte : info->calleeInterface->Id()->Name(); lambdaClassName.Append(objectName).Append("$").Append(info->name); - + ES2PANDA_ASSERT(lambdaProviderClass); auto *providerTypeReference = checker->AllocNode( checker->AllocNode( checker->AllocNode(lambdaProviderClass->AsETSObjectType()->Name(), checker->Allocator()), @@ -887,6 +900,7 @@ static ir::ClassDeclaration *CreateLambdaClass(public_lib::Context *ctx, checker CreateEmptyLambdaClassDeclaration(ctx, info, newTypeParams, fnInterface, lambdaProviderClass); auto classDefinition = classDeclaration->Definition(); if (info->isFunctionReference) { + ES2PANDA_ASSERT(callee->Function()); classDefinition->SetFunctionalReferenceReferencedMethod(callee); classDefinition->SetModifiers(classDefinition->Modifiers() | ir::ClassDefinitionModifiers::FUNCTIONAL_REFERENCE); @@ -953,8 +967,10 @@ static ir::ETSNewClassInstanceExpression *CreateConstructorCall(public_lib::Cont auto *newExpr = util::NodeAllocator::ForceSetParent( allocator, allocator->New(constructedType, allocator), std::move(args)); auto *lambdaOrFuncRefParent = lambdaOrFuncRef->Parent(); + ES2PANDA_ASSERT(newExpr); newExpr->SetParent(lambdaOrFuncRefParent); // NOTE(dslynko, #19869): Required for correct debug-info generation + ES2PANDA_ASSERT(newExpr); newExpr->SetRange(lambdaOrFuncRefParent != nullptr ? lambdaOrFuncRefParent->Range() : lambdaOrFuncRef->Range()); auto *nearestScope = NearestScope(lambdaOrFuncRef); @@ -1041,6 +1057,7 @@ static ir::ScriptFunction *GetWrappingLambdaParentFunction(public_lib::Context * } bodyStmts.push_back(stmt); func->SetBody(util::NodeAllocator::ForceSetParent(allocator, allocator, std::move(bodyStmts))); + ES2PANDA_ASSERT(func->Body()); func->Body()->SetParent(func); return func; } @@ -1056,6 +1073,7 @@ static ir::ArrowFunctionExpression *CreateWrappingLambda(public_lib::Context *ct auto *func = GetWrappingLambdaParentFunction(ctx, funcRef, signature); auto *lambda = util::NodeAllocator::ForceSetParent(allocator, func, allocator); + ES2PANDA_ASSERT(lambda); lambda->SetParent(parent); auto *nearestScope = NearestScope(lambda); @@ -1143,6 +1161,7 @@ static ir::AstNode *ConvertFunctionReference(public_lib::Context *ctx, ir::Expre ES2PANDA_ASSERT(funcRef->TsType()->IsETSArrowType()); auto *lambdaClass = CreateLambdaClass(ctx, funcRef->TsType()->AsETSFunctionType(), method, &info); auto *constructorCall = CreateConstructorCall(ctx, funcRef, lambdaClass, &info); + ES2PANDA_ASSERT(constructorCall); if (constructorCall->TsType()->IsETSObjectType()) { constructorCall->TsType()->AsETSObjectType()->AddObjectFlag(checker::ETSObjectFlags::FUNCTIONAL_REFERENCE); } @@ -1166,6 +1185,7 @@ static bool IsFunctionOrMethodCall(checker::ETSChecker *checker, ir::CallExpress // Not skip if invoke pattern Union.() where field is of ETSArrowType if (callee->IsMemberExpression()) { auto me = callee->AsMemberExpression(); + ES2PANDA_ASSERT(me->TsType()); if (me->Object()->TsType() != nullptr && checker->GetApparentType(me->Object()->TsType())->IsETSUnionType() && me->TsType()->IsETSMethodType()) { return true; @@ -1183,6 +1203,7 @@ static bool IsFunctionOrMethodCall(checker::ETSChecker *checker, ir::CallExpress return var != nullptr && !IsVariableOriginalAccessor(var) && (var->Flags() & varbinder::VariableFlags::METHOD) != 0; } +// CC-OFFNXT(G.FUN.01, huge_method, huge_method[C++]) solid logic static ir::AstNode *InsertInvokeCall(public_lib::Context *ctx, ir::CallExpression *call) { auto *allocator = ctx->allocator; @@ -1205,6 +1226,7 @@ static ir::AstNode *InsertInvokeCall(public_lib::Context *ctx, ir::CallExpressio checker::PropertySearchFlags::SEARCH_IN_INTERFACES); ES2PANDA_ASSERT(prop != nullptr); auto *invoke0Id = allocator->New(invokeMethodName, allocator); + ES2PANDA_ASSERT(invoke0Id); invoke0Id->SetTsType(prop->TsType()); invoke0Id->SetVariable(prop); diff --git a/ets2panda/compiler/lowering/ets/lateInitialization.cpp b/ets2panda/compiler/lowering/ets/lateInitialization.cpp index 6c57beb75e..87e878ac13 100644 --- a/ets2panda/compiler/lowering/ets/lateInitialization.cpp +++ b/ets2panda/compiler/lowering/ets/lateInitialization.cpp @@ -36,6 +36,7 @@ ir::ClassProperty *TransformerClassProperty(public_lib::Context *ctx, ir::ClassP auto annotationType = checker->CreateETSUnionType({property->TsType(), checker->GlobalETSUndefinedType()}); auto typeAnnotation = allocator->New(annotationType, allocator); + ES2PANDA_ASSERT(typeAnnotation); typeAnnotation->SetParent(property); typeAnnotation->SetTsType(annotationType); property->SetTypeAnnotation(typeAnnotation); @@ -76,6 +77,7 @@ static ir::AstNode *TransformerMemberExpression(ir::MemberExpression *memberExpr blockStatements.push_back(parser->CreateFormattedStatement(ss.str(), name)); blockStatements.push_back(parser->CreateFormattedStatement("@@I1 as @@T2", name, typeNode)); auto *res = util::NodeAllocator::ForceSetParent(allocator, std::move(blockStatements)); + ES2PANDA_ASSERT(res); res->SetParent(parent); Recheck(ctx->phaseManager, varbinder, checker, res); diff --git a/ets2panda/ir/ets/etsClassLiteral.cpp b/ets2panda/ir/ets/etsClassLiteral.cpp index fa65001a99..ba0830fb30 100644 --- a/ets2panda/ir/ets/etsClassLiteral.cpp +++ b/ets2panda/ir/ets/etsClassLiteral.cpp @@ -72,6 +72,7 @@ ETSClassLiteral *ETSClassLiteral::Clone(ArenaAllocator *const allocator, AstNode expr->SetParent(clone); } if (parent != nullptr) { + ES2PANDA_ASSERT(clone); clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsFunctionType.cpp b/ets2panda/ir/ets/etsFunctionType.cpp index 097b326d26..ebe73b6a52 100644 --- a/ets2panda/ir/ets/etsFunctionType.cpp +++ b/ets2panda/ir/ets/etsFunctionType.cpp @@ -137,6 +137,7 @@ ETSFunctionType *ETSFunctionType::Clone(ArenaAllocator *const allocator, AstNode if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone)); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/ets/etsKeyofType.cpp b/ets2panda/ir/ets/etsKeyofType.cpp index 6407914ab7..c3b65e2961 100644 --- a/ets2panda/ir/ets/etsKeyofType.cpp +++ b/ets2panda/ir/ets/etsKeyofType.cpp @@ -64,6 +64,7 @@ checker::Type *ETSKeyofType::GetType(checker::ETSChecker *checker) } auto *typeReference = type_->GetType(checker); + ES2PANDA_ASSERT(typeReference); if (typeReference->IsETSPrimitiveType()) { typeReference = checker->MaybeBoxType(typeReference); @@ -88,6 +89,7 @@ ETSKeyofType *ETSKeyofType::Clone(ArenaAllocator *const allocator, AstNode *cons { TypeNode *type = type_->Clone(allocator, nullptr); ETSKeyofType *clone = allocator->New(type, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsNeverType.cpp b/ets2panda/ir/ets/etsNeverType.cpp index 3f40e34750..0c0cbe895a 100644 --- a/ets2panda/ir/ets/etsNeverType.cpp +++ b/ets2panda/ir/ets/etsNeverType.cpp @@ -68,6 +68,7 @@ checker::Type *ETSNeverType::GetType([[maybe_unused]] checker::ETSChecker *check ETSNeverType *ETSNeverType::Clone(ArenaAllocator *allocator, AstNode *parent) { auto *const clone = allocator->New(allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp index 638627789f..6031857627 100644 --- a/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewArrayInstanceExpression.cpp @@ -84,6 +84,7 @@ ETSNewArrayInstanceExpression *ETSNewArrayInstanceExpression::Clone(ArenaAllocat auto *const typeRef = typeReference_ != nullptr ? typeReference_->Clone(allocator, nullptr) : nullptr; auto *const dimension = dimension_ != nullptr ? dimension_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(typeRef, dimension); + ES2PANDA_ASSERT(clone); if (typeRef != nullptr) { typeRef->SetParent(clone); diff --git a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp index 4a32953e5d..7c0b525c0e 100644 --- a/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewClassInstanceExpression.cpp @@ -109,6 +109,7 @@ ETSNewClassInstanceExpression *ETSNewClassInstanceExpression::Clone(ArenaAllocat AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp index f18b4e7a3a..08ff84bcf4 100644 --- a/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp +++ b/ets2panda/ir/ets/etsNewMultiDimArrayInstanceExpression.cpp @@ -115,6 +115,7 @@ ETSNewMultiDimArrayInstanceExpression *ETSNewMultiDimArrayInstanceExpression::Cl AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsNonNullishTypeNode.cpp b/ets2panda/ir/ets/etsNonNullishTypeNode.cpp index 14226f3c0f..00d68dbfce 100644 --- a/ets2panda/ir/ets/etsNonNullishTypeNode.cpp +++ b/ets2panda/ir/ets/etsNonNullishTypeNode.cpp @@ -69,6 +69,7 @@ ETSNonNullishTypeNode *ETSNonNullishTypeNode::Clone(ArenaAllocator *allocator, A { TypeNode *typeNode = typeNode_->Clone(allocator, nullptr); ETSNonNullishTypeNode *clone = allocator->New(typeNode, allocator); + ES2PANDA_ASSERT(clone); clone->SetParent(parent); clone->typeNode_->SetParent(clone); return clone; diff --git a/ets2panda/ir/ets/etsNullishTypes.cpp b/ets2panda/ir/ets/etsNullishTypes.cpp index 0957d162a4..c30404e1eb 100644 --- a/ets2panda/ir/ets/etsNullishTypes.cpp +++ b/ets2panda/ir/ets/etsNullishTypes.cpp @@ -68,6 +68,7 @@ checker::Type *ETSUndefinedType::GetType([[maybe_unused]] checker::ETSChecker *c ETSUndefinedType *ETSUndefinedType::Clone(ArenaAllocator *allocator, AstNode *parent) { auto *const clone = allocator->New(allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); @@ -76,6 +77,7 @@ ETSUndefinedType *ETSUndefinedType::Clone(ArenaAllocator *allocator, AstNode *pa if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone)); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/ets/etsPackageDeclaration.cpp b/ets2panda/ir/ets/etsPackageDeclaration.cpp index 277abfc2d3..e6de02bf1e 100644 --- a/ets2panda/ir/ets/etsPackageDeclaration.cpp +++ b/ets2panda/ir/ets/etsPackageDeclaration.cpp @@ -69,6 +69,7 @@ ETSPackageDeclaration *ETSPackageDeclaration::Clone(ArenaAllocator *const alloca { auto const name = name_ != nullptr ? name_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(name); + ES2PANDA_ASSERT(clone); if (name != nullptr) { name->SetParent(clone); diff --git a/ets2panda/ir/ets/etsParameterExpression.cpp b/ets2panda/ir/ets/etsParameterExpression.cpp index 300573755b..9292f3e75f 100644 --- a/ets2panda/ir/ets/etsParameterExpression.cpp +++ b/ets2panda/ir/ets/etsParameterExpression.cpp @@ -287,6 +287,7 @@ ETSParameterExpression *ETSParameterExpression::Clone(ArenaAllocator *const allo initializer->SetParent(clone); } + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsParameterExpression.h b/ets2panda/ir/ets/etsParameterExpression.h index ab6ee08144..a04ffa056e 100644 --- a/ets2panda/ir/ets/etsParameterExpression.h +++ b/ets2panda/ir/ets/etsParameterExpression.h @@ -55,6 +55,7 @@ public: void SetIdent(Identifier *ident) noexcept { this->GetOrCreateHistoryNodeAs()->ident_ = ident; + ES2PANDA_ASSERT(ident); ident->SetParent(this); } diff --git a/ets2panda/ir/ets/etsPrimitiveType.cpp b/ets2panda/ir/ets/etsPrimitiveType.cpp index 6fc11fec68..cd4a16ccc6 100644 --- a/ets2panda/ir/ets/etsPrimitiveType.cpp +++ b/ets2panda/ir/ets/etsPrimitiveType.cpp @@ -162,6 +162,7 @@ ETSPrimitiveType *ETSPrimitiveType::Clone(ArenaAllocator *const allocator, AstNo if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone)); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/ets/etsStringLiteralType.cpp b/ets2panda/ir/ets/etsStringLiteralType.cpp index 178160de40..26da8a4ede 100644 --- a/ets2panda/ir/ets/etsStringLiteralType.cpp +++ b/ets2panda/ir/ets/etsStringLiteralType.cpp @@ -77,6 +77,7 @@ ETSStringLiteralType *ETSStringLiteralType::Clone(ArenaAllocator *allocator, Ast if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone)); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/ets/etsTuple.cpp b/ets2panda/ir/ets/etsTuple.cpp index 3b143a0872..968b287249 100644 --- a/ets2panda/ir/ets/etsTuple.cpp +++ b/ets2panda/ir/ets/etsTuple.cpp @@ -120,6 +120,7 @@ checker::Type *ETSTuple::GetType(checker::ETSChecker *const checker) auto *tupleType = checker->ProgramAllocator()->New(checker, typeList); if (IsReadonlyType()) { + ES2PANDA_ASSERT(checker->GetReadonlyType(tupleType)); tupleType = checker->GetReadonlyType(tupleType)->AsETSTupleType(); } @@ -130,6 +131,7 @@ checker::Type *ETSTuple::GetType(checker::ETSChecker *const checker) ETSTuple *ETSTuple::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(allocator, size_); + ES2PANDA_ASSERT(clone); clone->AddModifier(flags_); diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index 8a79259d94..95812f806b 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -298,6 +298,7 @@ ETSTypeReferencePart *ETSTypeReferencePart::Clone(ArenaAllocator *const allocato prevClone->SetParent(clone); } + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } diff --git a/ets2panda/ir/ets/etsUnionType.cpp b/ets2panda/ir/ets/etsUnionType.cpp index 19f2311988..0a74affb97 100644 --- a/ets2panda/ir/ets/etsUnionType.cpp +++ b/ets2panda/ir/ets/etsUnionType.cpp @@ -126,6 +126,7 @@ ETSUnionType *ETSUnionType::Clone(ArenaAllocator *const allocator, AstNode *cons if (!Annotations().empty()) { ArenaVector annotationUsages {allocator->Adapter()}; for (auto *annotationUsage : Annotations()) { + ES2PANDA_ASSERT(annotationUsage->Clone(allocator, clone)); annotationUsages.push_back(annotationUsage->Clone(allocator, clone)->AsAnnotationUsage()); } clone->SetAnnotations(std::move(annotationUsages)); diff --git a/ets2panda/ir/expressions/arrayExpression.cpp b/ets2panda/ir/expressions/arrayExpression.cpp index 3e0a753d33..76bc0c22bc 100644 --- a/ets2panda/ir/expressions/arrayExpression.cpp +++ b/ets2panda/ir/expressions/arrayExpression.cpp @@ -48,6 +48,7 @@ ArrayExpression::ArrayExpression([[maybe_unused]] Tag const tag, ArrayExpression ArrayExpression *ArrayExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } @@ -345,6 +346,7 @@ checker::Type *ArrayExpression::CheckPattern(checker::TSChecker *checker) index--; } + ES2PANDA_ASSERT(desc); const checker::TupleTypeInfo tupleTypeInfo = {combinedFlags, minLength, static_cast(desc->properties.size()), false}; return checker->CreateTupleType(desc, std::move(elementFlags), tupleTypeInfo); @@ -422,6 +424,7 @@ checker::VerifiedType ArrayExpression::Check(checker::ETSChecker *checker) std::optional ArrayExpression::ExtractPossiblePreferredType(checker::Type *type) { + ES2PANDA_ASSERT(type); if (type->IsETSArrayType() || type->IsETSTupleType() || type->IsETSResizableArrayType()) { return std::make_optional(type); } diff --git a/ets2panda/ir/expressions/arrowFunctionExpression.cpp b/ets2panda/ir/expressions/arrowFunctionExpression.cpp index 772cf69fc0..73168b0bd2 100644 --- a/ets2panda/ir/expressions/arrowFunctionExpression.cpp +++ b/ets2panda/ir/expressions/arrowFunctionExpression.cpp @@ -83,12 +83,14 @@ checker::VerifiedType ArrowFunctionExpression::Check(checker::ETSChecker *checke ArrowFunctionExpression::ArrowFunctionExpression(ArrowFunctionExpression const &other, ArenaAllocator *const allocator) : JsDocAllowed>(static_cast(other), allocator) { + ES2PANDA_ASSERT(other.func_->Clone(allocator, this)); func_ = other.func_->Clone(allocator, this)->AsScriptFunction(); } ArrowFunctionExpression *ArrowFunctionExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(*this, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); @@ -115,6 +117,7 @@ ir::TypeNode *ArrowFunctionExpression::CreateReturnNodeFromType(checker::ETSChec auto *ident = checker->AllocNode(util::StringView(""), checker->Allocator()); auto *const part = checker->AllocNode(ident, checker->Allocator()); auto *returnNode = checker->AllocNode(part, checker->Allocator()); + ES2PANDA_ASSERT(returnNode); returnNode->SetTsType(returnType); return returnNode; } diff --git a/ets2panda/ir/expressions/assignmentExpression.cpp b/ets2panda/ir/expressions/assignmentExpression.cpp index d6ff928480..2505910c5f 100644 --- a/ets2panda/ir/expressions/assignmentExpression.cpp +++ b/ets2panda/ir/expressions/assignmentExpression.cpp @@ -169,6 +169,7 @@ AssignmentExpression *AssignmentExpression::Clone(ArenaAllocator *const allocato auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(Tag {}, *this, left, right); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); diff --git a/ets2panda/ir/expressions/awaitExpression.cpp b/ets2panda/ir/expressions/awaitExpression.cpp index 6071bd4155..d9e6b54668 100644 --- a/ets2panda/ir/expressions/awaitExpression.cpp +++ b/ets2panda/ir/expressions/awaitExpression.cpp @@ -74,6 +74,7 @@ AwaitExpression *AwaitExpression::Clone(ArenaAllocator *const allocator, AstNode { auto *const argument = argument_ != nullptr ? argument_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(argument); + ES2PANDA_ASSERT(clone); if (argument != nullptr) { argument->SetParent(clone); diff --git a/ets2panda/ir/expressions/binaryExpression.cpp b/ets2panda/ir/expressions/binaryExpression.cpp index 21babd5626..ddfd3f3a06 100644 --- a/ets2panda/ir/expressions/binaryExpression.cpp +++ b/ets2panda/ir/expressions/binaryExpression.cpp @@ -99,6 +99,7 @@ BinaryExpression *BinaryExpression::Clone(ArenaAllocator *const allocator, AstNo auto *const left = left_ != nullptr ? left_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const right = right_ != nullptr ? right_->Clone(allocator, nullptr)->AsExpression() : nullptr; auto *const clone = allocator->New(left, right, operator_); + ES2PANDA_ASSERT(clone); if (operationType_ != nullptr) { clone->SetOperationType(operationType_); diff --git a/ets2panda/ir/expressions/binaryExpression.h b/ets2panda/ir/expressions/binaryExpression.h index 97de660fce..87c4377c86 100644 --- a/ets2panda/ir/expressions/binaryExpression.h +++ b/ets2panda/ir/expressions/binaryExpression.h @@ -113,12 +113,14 @@ public: void SetLeft(Expression *expr) noexcept { left_ = expr; + ES2PANDA_ASSERT(left_); left_->SetParent(this); } void SetRight(Expression *expr) noexcept { right_ = expr; + ES2PANDA_ASSERT(right_); right_->SetParent(this); } diff --git a/ets2panda/ir/expressions/blockExpression.cpp b/ets2panda/ir/expressions/blockExpression.cpp index c38cb57710..853f4973fc 100644 --- a/ets2panda/ir/expressions/blockExpression.cpp +++ b/ets2panda/ir/expressions/blockExpression.cpp @@ -40,6 +40,7 @@ BlockExpression::BlockExpression([[maybe_unused]] Tag const tag, BlockExpression BlockExpression *BlockExpression::Clone(ArenaAllocator *const allocator, AstNode *const parent) { auto *const clone = allocator->New(Tag {}, *this, allocator); + ES2PANDA_ASSERT(clone); if (parent != nullptr) { clone->SetParent(parent); } -- Gitee From 6481ec61215b42e8a6a0469d942ca78ce8093a9d Mon Sep 17 00:00:00 2001 From: huyunhui Date: Mon, 7 Jul 2025 14:52:43 +0800 Subject: [PATCH 049/107] Fix bug of annotation Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKHGT Signed-off-by: huyunhui --- ets2panda/checker/ets/typeCheckingHelpers.cpp | 2 +- .../annotation_usage_wrong_ref.ets | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 182a3fd6f3..939a456667 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -1157,7 +1157,7 @@ void ETSChecker::HandleAnnotationRetention(ir::AnnotationUsage *anno, ir::Annota void ETSChecker::CheckStandardAnnotation(ir::AnnotationUsage *anno) { - if (anno->GetBaseName()->Variable() == nullptr) { + if (anno->GetBaseName()->Variable() == nullptr || IsTypeError(anno->GetBaseName()->TsType())) { return; } ES2PANDA_ASSERT(anno->GetBaseName()->Variable()->Declaration()->Node()->AsAnnotationDeclaration() != nullptr); diff --git a/ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets new file mode 100644 index 0000000000..6aa297c618 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/annotations_tests/annotation_usage_wrong_ref.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024-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. + */ + +function foo() {} + +@/* @@ label */foo +@interface anno {} + +/* @@@ label Error TypeError: Cannot find type 'foo'. */ \ No newline at end of file -- Gitee From b4b73a5e74d9367041cdbf4e5190c9e22c1c406e Mon Sep 17 00:00:00 2001 From: Boglarka Haag Date: Thu, 26 Jun 2025 13:27:46 +0200 Subject: [PATCH 050/107] No indexed signatures are allowed Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICHTXP Reason: Uninformative error messages. Description: Modified parser to give better error messages. Changed back error message on indexer calls to a more informative one. Fixes internal issue: #23483 Signed-off-by: Haag Boglarka --- ets2panda/ir/expressions/memberExpression.cpp | 2 +- ets2panda/parser/ETSparser.cpp | 3 ++ ets2panda/parser/ETSparser.h | 1 + ets2panda/parser/ETSparserClasses.cpp | 24 +++++++++ ets2panda/parser/parserImpl.cpp | 50 +++++++++++++++++++ ets2panda/parser/parserImpl.h | 2 + .../ets/dynamic-field-declaration.ets | 2 +- .../not_constructible_types.ets | 2 +- .../ets/FixedArray/unexpected_token_31.ets | 2 +- .../test/ast/parser/ets/ambient_indexer_2.ets | 8 +-- .../ets/index_not_support_such_type.ets | 2 +- .../parser/ets/index_signature_error_1.ets | 27 ++++++++++ .../parser/ets/index_signature_error_2.ets | 27 ++++++++++ .../parser/ets/non-ambient_call_signature.ets | 3 +- .../parser/ets/non_proper_index_method.ets | 2 +- .../ets/recursive_exported_structure.ets | 9 +--- .../parser/ets/typenode_clone_brokentype.ets | 2 +- .../ast/parser/ets/unexpected_token_31.ets | 2 +- .../ast/parser/ets/unexpected_token_63.ets | 1 - .../ast/parser/ets/wrong_context_class_4.ets | 2 +- 20 files changed, 146 insertions(+), 27 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/index_signature_error_1.ets create mode 100644 ets2panda/test/ast/parser/ets/index_signature_error_2.ets diff --git a/ets2panda/ir/expressions/memberExpression.cpp b/ets2panda/ir/expressions/memberExpression.cpp index cc6fc7d172..6c0bc3f2ef 100644 --- a/ets2panda/ir/expressions/memberExpression.cpp +++ b/ets2panda/ir/expressions/memberExpression.cpp @@ -416,7 +416,7 @@ checker::Type *MemberExpression::CheckIndexAccessMethod(checker::ETSChecker *che isSetter ? compiler::Signatures::SET_INDEX_METHOD : compiler::Signatures::GET_INDEX_METHOD; auto *const method = objType_->GetProperty(methodName, searchFlag); if (method == nullptr || !method->HasFlag(varbinder::VariableFlags::METHOD)) { - checker->LogError(diagnostic::ERROR_ARKTS_NO_PROPERTIES_BY_INDEX, {}, Start()); + checker->LogError(diagnostic::NO_INDEX_ACCESS_METHOD, {}, Start()); return nullptr; } diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9e2059c27d..d5c9455fad 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -709,6 +709,9 @@ ir::AstNode *ETSParser::ParseInnerRest(const ArenaVector &propert Lexer()->NextToken(); return AllocBrokenStatement(rangeToken); } + if (memberName->IsErrorPlaceHolder()) { + return AllocBrokenStatement(startLoc); + } if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index b9be64d56c..501ce1a0b3 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -229,6 +229,7 @@ private: ir::ModifierFlags ParseClassModifiers(); ir::ModifierFlags ParseInterfaceMethodModifiers(); ir::AstNode *ParseInterfaceField(); + void ParseIndexedSignature(); ir::TypeNode *ParseInterfaceTypeAnnotation(ir::Identifier *name); void ParseInterfaceModifiers(ir::ModifierFlags &fieldModifiers, bool &optionalField); ir::OverloadDeclaration *ParseInterfaceOverload(ir::ModifierFlags modifiers); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 8807006489..83986af1d2 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -1059,11 +1059,30 @@ void ETSParser::ParseInterfaceModifiers(ir::ModifierFlags &fieldModifiers, bool } } +void ETSParser::ParseIndexedSignature() +{ + ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET); + Lexer()->NextToken(); + if (Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + return; + } + auto *name = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + Lexer()->NextToken(); + ParseInterfaceTypeAnnotation(name); + + if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET)) { + return; + } + Lexer()->NextToken(); + ParseInterfaceTypeAnnotation(name); +} + ir::AstNode *ETSParser::ParseInterfaceField() { ES2PANDA_ASSERT(Lexer()->GetToken().Type() == lexer::TokenType::LITERAL_IDENT || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET || Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS); + ir::ModifierFlags fieldModifiers = ir::ModifierFlags::PUBLIC; auto startLoc = Lexer()->GetToken().Start(); @@ -1082,6 +1101,11 @@ ir::AstNode *ETSParser::ParseInterfaceField() return property; } } + if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { + ParseIndexedSignature(); + LogError(diagnostic::ERROR_ARKTS_NO_PROPERTIES_BY_INDEX, {}, startLoc); + return AllocBrokenExpression(Lexer()->GetToken().Start()); + } name->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 47b031611b..0f26457e32 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -1253,6 +1253,51 @@ util::StringView ParserImpl::ParseSymbolIteratorIdentifier() const noexcept return util::StringView {compiler::Signatures::ITERATOR_METHOD}; } +void ParserImpl::EatTypeAnnotation() +{ + lexer_->NextToken(); // eat ':' or '|' + if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + LogUnexpectedToken(lexer_->GetToken()); + auto pos = lexer_->Save(); + lexer_->NextToken(); + while (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + // just skip usls tokens, we have an identifier after + lexer_->Rewind(pos); + lexer_->NextToken(); + pos = lexer_->Save(); + } + if (lexer_->GetToken().Type() == lexer::TokenType::LITERAL_IDENT) { + // if next token is not an ident, so current token should be an identifier + // and we set it as literal ident + lexer_->GetToken().SetTokenType(lexer::TokenType::LITERAL_IDENT); + lexer_->GetToken().SetTokenStr(ERROR_LITERAL); + } + } + lexer_->NextToken(); // eat type + if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_BITWISE_OR) { + EatTypeAnnotation(); + } +} + +void ParserImpl::ParseIndexSignature() +{ + if (lexer_->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + return; + } + lexer_->NextToken(); // eat param + + if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_COLON) { + return; + } + + EatTypeAnnotation(); + + if (!lexer_->TryEatTokenType(lexer::TokenType::PUNCTUATOR_RIGHT_SQUARE_BRACKET)) { + return; + } + EatTypeAnnotation(); +} + ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, bool isUserDefinedType, TypeAnnotationParsingOptions options) { @@ -1283,6 +1328,11 @@ ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, } else if (tokenType == lexer::TokenType::PUNCTUATOR_LEFT_SQUARE_BRACKET) { // Special case for processing of special '[Symbol.iterator]` identifier using in stdlib. tokenName = ParseSymbolIteratorIdentifier(); + if (tokenName.Empty()) { + LogError(diagnostic::ERROR_ARKTS_NO_PROPERTIES_BY_INDEX, {}); + ParseIndexSignature(); + return AllocBrokenExpression(Lexer()->GetToken().Start()); + } } if (tokenName.Empty()) { diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 169f3c2e7f..296541ebf9 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -241,6 +241,8 @@ protected: return false; } + void ParseIndexSignature(); + void EatTypeAnnotation(); util::StringView ParseSymbolIteratorIdentifier() const noexcept; ir::Identifier *ExpectIdentifier(bool isReference = false, bool isUserDefinedType = false, TypeAnnotationParsingOptions options = TypeAnnotationParsingOptions::REPORT_ERROR); diff --git a/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets b/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets index 1213452ed7..ad2a27ac6c 100644 --- a/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets +++ b/ets2panda/test/ast/compiler/ets/dynamic-field-declaration.ets @@ -20,4 +20,4 @@ class Point { let p: Point = {x: 1, y: 2} console.log(p["x"]) -/* @@? 21:13 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ \ No newline at end of file +/* @@? 21:13 Error TypeError: Object type doesn't have proper index access method. */ \ No newline at end of file diff --git a/ets2panda/test/ast/compiler/ets/type_error_processing/not_constructible_types.ets b/ets2panda/test/ast/compiler/ets/type_error_processing/not_constructible_types.ets index 4341a3928c..46b03a8e16 100644 --- a/ets2panda/test/ast/compiler/ets/type_error_processing/not_constructible_types.ets +++ b/ets2panda/test/ast/compiler/ets/type_error_processing/not_constructible_types.ets @@ -34,6 +34,6 @@ WeakSet [12] = new undefined() /* @@? 19:1 Error TypeError: Type 'never' is not constructible. */ /* @@? 20:1 Error TypeError: This expression is not constructible. */ /* @@? 23:1 Error TypeError: The union type is not constructible. */ -/* @@? 26:1 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 26:1 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 26:1 Error SyntaxError: Class cannot be used as object. */ /* @@? 26:16 Error TypeError: Type 'undefined' is not constructible. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets index ef1a3529d1..8190270528 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/unexpected_token_31.ets @@ -28,5 +28,5 @@ function foo(...^number: FixedArray): int { /* @@? 16:48 Error SyntaxError: Unexpected token '{'. */ /* @@? 17:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 17:12 Error TypeError: Type name 'number' used in the wrong context */ -/* @@? 17:12 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 17:12 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 17:12 Error TypeError: All return statements in the function should be empty or have a value. */ diff --git a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets index 424271f881..d1c5273f0c 100644 --- a/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets +++ b/ets2panda/test/ast/parser/ets/ambient_indexer_2.ets @@ -21,10 +21,4 @@ function main() { let a : A = new A(); } -/* @@? 17:6 Error SyntaxError: Unexpected token 'index'. */ -/* @@? 17:12 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:14 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ -/* @@? 17:20 Error SyntaxError: Field type annotation expected. */ -/* @@? 17:20 Error SyntaxError: Unexpected token ']'. */ -/* @@? 17:22 Error SyntaxError: Unexpected token ':'. */ -/* @@? 17:30 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:6 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets b/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets index 5a82a6fe4a..c713e31333 100644 --- a/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets +++ b/ets2panda/test/ast/parser/ets/index_not_support_such_type.ets @@ -26,4 +26,4 @@ function main() { /* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ /* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ /* @@? 18:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ -/* @@@ label Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/index_signature_error_1.ets b/ets2panda/test/ast/parser/ets/index_signature_error_1.ets new file mode 100644 index 0000000000..1b35a8935c --- /dev/null +++ b/ets2panda/test/ast/parser/ets/index_signature_error_1.ets @@ -0,0 +1,27 @@ +/* + * 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 StringArray { + [/* @@ label1 */index: number]: string +} +function getStringArray(): StringArray { + return /* @@ label2 */["a", "b", "c"] +} +let myArray: StringArray = getStringArray() +let secondItem = /* @@ label3 */myArray[1] + +/* @@@ label1 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label2 Error TypeError: Type 'Array' is not compatible with the enclosing method's return type 'StringArray' */ +/* @@@ label3 Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/index_signature_error_2.ets b/ets2panda/test/ast/parser/ets/index_signature_error_2.ets new file mode 100644 index 0000000000..8eee907561 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/index_signature_error_2.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ + +interface StringArray { + /* @@ label1 */[index: number]: string +} +function getStringArray(): StringArray { + return /* @@ label2 */["a", "b", "c"] +} +let myArray: StringArray = getStringArray() +let secondItem = /* @@ label3 */myArray[1] + +/* @@@ label1 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label2 Error TypeError: Type 'Array' is not compatible with the enclosing method's return type 'StringArray' */ +/* @@@ label3 Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets b/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets index a2ab27116b..a61d358039 100644 --- a/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets +++ b/ets2panda/test/ast/parser/ets/non-ambient_call_signature.ets @@ -15,10 +15,9 @@ class A{ /* @@ label */(a:number/* @@ label1 */)/* @@ label2 */:number -/* @@ label3 */} +} /* @@@ label Error SyntaxError: Unexpected token '('. */ /* @@@ label1 Error SyntaxError: Unexpected token ')'. */ /* @@@ label2 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:60 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ -/* @@@ label3 Error SyntaxError: Field type annotation expected. */ diff --git a/ets2panda/test/ast/parser/ets/non_proper_index_method.ets b/ets2panda/test/ast/parser/ets/non_proper_index_method.ets index 33fbc6131a..49fbed1717 100644 --- a/ets2panda/test/ast/parser/ets/non_proper_index_method.ets +++ b/ets2panda/test/ast/parser/ets/non_proper_index_method.ets @@ -30,4 +30,4 @@ function main() { /* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Long): void` */ /* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Float): void` */ /* @@? 22:5 Error TypeError: Call to `log` is ambiguous as `2` versions of `log` are available: `log(i: String): void` and `log(i: Double): void` */ -/* @@@ label Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@@ label Error TypeError: Object type doesn't have proper index access method. */ diff --git a/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets b/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets index 2785b592bd..90fd2ccf79 100644 --- a/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets +++ b/ets2panda/test/ast/parser/ets/recursive_exported_structure.ets @@ -98,12 +98,5 @@ export default _exported; /* @@? 62:12 Error SyntaxError: Label must be followed by a loop statement. */ /* @@? 62:12 Error TypeError: Type name 'IndexableType' used in the wrong context */ /* @@? 66:36 Error TypeError: Interfaces cannot extend classes, only other interfaces. */ -/* @@? 73:6 Error SyntaxError: Unexpected token 'key'. */ -/* @@? 73:9 Error SyntaxError: Unexpected token ':'. */ -/* @@? 73:17 Error SyntaxError: Field type annotation expected. */ -/* @@? 73:17 Error SyntaxError: Unexpected token ']'. */ -/* @@? 73:18 Error SyntaxError: Unexpected token ':'. */ -/* @@? 73:30 Error SyntaxError: Field type annotation expected. */ -/* @@? 73:31 Error SyntaxError: Unexpected token '|'. */ -/* @@? 73:46 Error SyntaxError: Field type annotation expected. */ +/* @@? 73:6 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ /* @@? 76:16 Error TypeError: Cannot cast type 'ExportedStructure' to 'Record Double|Record Double>>' */ diff --git a/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets b/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets index c3712f9c1f..f955112a64 100644 --- a/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets +++ b/ets2panda/test/ast/parser/ets/typenode_clone_brokentype.ets @@ -53,7 +53,7 @@ declare const broken2: AnotherBroken; /* @@? 31:14 Error SyntaxError: Unexpected token ','. */ /* @@? 32:12 Error SyntaxError: Class cannot be used as object. */ /* @@? 32:12 Error SyntaxError: Label must be followed by a loop statement. */ -/* @@? 32:12 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 32:12 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 36:27 Error TypeError: Cannot find type 'UndefinedInterface'. */ /* @@? 39:35 Error TypeError: Cannot find type 'any'. */ /* @@? 40:38 Error TypeError: Cannot find type 'any'. */ \ No newline at end of file diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets index b545847e80..d7442c979c 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_31.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_31.ets @@ -28,5 +28,5 @@ function foo(...^number: int[]): int { /* @@? 16:38 Error SyntaxError: Unexpected token '{'. */ /* @@? 17:5 Error SyntaxError: return keyword should be used in function body. */ /* @@? 17:12 Error TypeError: Type name 'number' used in the wrong context */ -/* @@? 17:12 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 17:12 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 17:12 Error TypeError: All return statements in the function should be empty or have a value. */ diff --git a/ets2panda/test/ast/parser/ets/unexpected_token_63.ets b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets index ec6024e988..342f45a066 100644 --- a/ets2panda/test/ast/parser/ets/unexpected_token_63.ets +++ b/ets2panda/test/ast/parser/ets/unexpected_token_63.ets @@ -33,7 +33,6 @@ class A { /* @@? 17:29 Error SyntaxError: Unexpected token ':'. */ /* @@? 17:31 Error SyntaxError: number is a predefined type, cannot be used as an identifier */ /* @@? 17:37 Error SyntaxError: Unexpected token ')'. */ -/* @@? 17:37 Error SyntaxError: Field type annotation expected. */ /* @@? 17:39 Error SyntaxError: Unexpected token '{'. */ /* @@? 18:3 Error SyntaxError: Unexpected token 'while'. */ /* @@? 18:8 Error SyntaxError: Unexpected token '('. */ diff --git a/ets2panda/test/ast/parser/ets/wrong_context_class_4.ets b/ets2panda/test/ast/parser/ets/wrong_context_class_4.ets index 531f3707e9..79ccb2bf3b 100644 --- a/ets2panda/test/ast/parser/ets/wrong_context_class_4.ets +++ b/ets2panda/test/ast/parser/ets/wrong_context_class_4.ets @@ -26,5 +26,5 @@ function main() a[3] } -/* @@? 26:5 Error TypeError: Indexed signatures are not allowed. Use arrays instead! */ +/* @@? 26:5 Error TypeError: Object type doesn't have proper index access method. */ /* @@? 26:5 Error SyntaxError: Class cannot be used as object. */ -- Gitee From 9c82efe7453572ab9e92c7fc16a74f590097eb7a Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Sun, 6 Jul 2025 17:46:03 +0800 Subject: [PATCH 051/107] fix crash when redefine array Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKACL?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ets/object.cpp | 6 +++++ .../ets/redefine_class/redefine_array.ets | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index ced96af24f..51262b80d7 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -1263,6 +1263,12 @@ void ETSChecker::CheckClassDefinition(ir::ClassDefinition *classDef) classType->SuperType()->GetDeclNode()->Check(this); } + if (classType->GetDeclNode() != classDef) { + ES2PANDA_ASSERT(IsAnyError()); + classDef->SetTsType(GlobalTypeError()); + return; + } + auto newStatus = checker::CheckerStatus::IN_CLASS; if (Context().ContainingClass() != classType) { classType->SetEnclosingType(Context().ContainingClass()); diff --git a/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets b/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.ets new file mode 100644 index 0000000000..ec66c92c5e --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/redefine_class/redefine_array.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. + */ + +package escompat; + +class ArrayKeysIterator { + private a: Array +} + +export class Array { + a: T +} + +/* @@? 1:3 Error TypeError: Class 'Array' is already defined. */ \ No newline at end of file -- Gitee From 08e2f93e81681a9246e7a5768fb253594597e3a6 Mon Sep 17 00:00:00 2001 From: xingshunxiang Date: Wed, 2 Jul 2025 10:31:58 +0800 Subject: [PATCH 052/107] function signature mismatch Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJH9A?from=project-issue Description: when function contain lambda as param, some situation met unexpected CTE Reason: 1. when the typeAnnotation of the args is TypeReference(TypeAlias), We have omitted some scenarios, for example, TypeReference(TypeAlias) may contain ETSFunctionType. 2. when handle the union type, we should compare the the args count for every function in union type, for example, when union type U is (()=>void) | ((n:number)=>void), then both () => {} a (n:number) => {} can be assign to U, because U is father type of ()=>void and (n:number)=>void Tests: ninja tests passed tests/tests-u-runner/runner.sh --ets-cts --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --ets-func-tests --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --astchecker --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --ets-runtime --show-progress --build-dir x64.release --processes=all passed tests/tests-u-runner/runner.sh --parser --no-js --show-progress --build-dir x64.release --processes=all passed Signed-off-by: xingshunxiang --- ets2panda/checker/ets/helpers.cpp | 13 +++- ets2panda/checker/ets/typeCheckingHelpers.cpp | 27 ++----- .../test/runtime/ets/lambdaParamsInfer.ets | 26 +++++++ .../test/runtime/ets/lambdaParamsInfer2.ets | 75 ++++++++++++++++++ .../test/runtime/ets/lambdaParamsInfer3.ets | 76 +++++++++++++++++++ ets2panda/util/helpers.cpp | 18 +++++ ets2panda/util/helpers.h | 1 + 7 files changed, 213 insertions(+), 23 deletions(-) create mode 100644 ets2panda/test/runtime/ets/lambdaParamsInfer.ets create mode 100644 ets2panda/test/runtime/ets/lambdaParamsInfer2.ets create mode 100644 ets2panda/test/runtime/ets/lambdaParamsInfer3.ets diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index cbe5c880a3..3e19edf530 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -26,6 +26,7 @@ #include "evaluate/scopedDebugInfoPlugin.h" #include "compiler/lowering/scopesInit/scopesInitPhase.h" #include "compiler/lowering/util.h" +#include "util/helpers.h" namespace ark::es2panda::checker { @@ -2563,13 +2564,21 @@ std::vector ETSChecker::FindTypeInferenceArguments(const ArenaVectorAsETSUnionType()->Types()) { if (type->IsETSFunctionType()) { - return lambda->Params().size() == type->AsETSFunctionType()->Params().size(); + assignable |= lambda->Params().size() == type->AsETSFunctionType()->Params().size(); + continue; + } + + if (type->IsETSTypeReference()) { + auto aliasType = util::Helpers::DerefETSTypeReference(type); + assignable |= aliasType->IsETSFunctionType() && + lambda->Params().size() == aliasType->AsETSFunctionType()->Params().size(); } } - return false; + return assignable; } void ETSChecker::InferTypesForLambda(ir::ScriptFunction *lambda, ir::ETSFunctionType *calleeType, diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index 82bbbc5041..d29b7b1711 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -1389,24 +1389,6 @@ void ETSChecker::CheckUnboxedSourceTypeWithWideningAssignable(TypeRelation *rela } } -static ir::AstNode *DerefETSTypeReference(ir::AstNode *node) -{ - ES2PANDA_ASSERT(node->IsETSTypeReference()); - do { - auto *name = node->AsETSTypeReference()->Part()->GetIdent(); - - ES2PANDA_ASSERT(name->IsIdentifier()); - auto *var = name->AsIdentifier()->Variable(); - ES2PANDA_ASSERT(var != nullptr); - auto *declNode = var->Declaration()->Node(); - if (!declNode->IsTSTypeAliasDeclaration()) { - return declNode; - } - node = declNode->AsTSTypeAliasDeclaration()->TypeAnnotation(); - } while (node->IsETSTypeReference()); - return node; -} - // #22952: optional arrow leftovers bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction *lambda) { @@ -1416,7 +1398,7 @@ bool ETSChecker::CheckLambdaAssignable(ir::Expression *param, ir::ScriptFunction return false; } if (typeAnn->IsETSTypeReference() && !typeAnn->AsETSTypeReference()->TsType()->IsETSArrayType()) { - typeAnn = DerefETSTypeReference(typeAnn); + typeAnn = util::Helpers::DerefETSTypeReference(typeAnn); } if (!typeAnn->IsETSFunctionType()) { @@ -1442,7 +1424,7 @@ bool ETSChecker::CheckLambdaInfer(ir::AstNode *typeAnnotation, ir::ArrowFunction Type *const subParameterType) { if (typeAnnotation->IsETSTypeReference()) { - typeAnnotation = DerefETSTypeReference(typeAnnotation); + typeAnnotation = util::Helpers::DerefETSTypeReference(typeAnnotation); } if (!typeAnnotation->IsETSFunctionType()) { @@ -1461,7 +1443,10 @@ bool ETSChecker::CheckLambdaTypeAnnotation(ir::ETSParameterExpression *param, ir::ArrowFunctionExpression *const arrowFuncExpr, Type *const parameterType, TypeRelationFlag flags) { - auto *typeAnnotation = param->Ident()->TypeAnnotation(); + ir::AstNode *typeAnnotation = param->Ident()->TypeAnnotation(); + if (typeAnnotation->IsETSTypeReference()) { + typeAnnotation = util::Helpers::DerefETSTypeReference(typeAnnotation); + } auto checkInvocable = [&arrowFuncExpr, ¶meterType, this](TypeRelationFlag functionFlags) { Type *const argumentType = arrowFuncExpr->Check(this); functionFlags |= TypeRelationFlag::NO_THROW; diff --git a/ets2panda/test/runtime/ets/lambdaParamsInfer.ets b/ets2panda/test/runtime/ets/lambdaParamsInfer.ets new file mode 100644 index 0000000000..245a8066c7 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambdaParamsInfer.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. + */ + +type Callback = (() => void) +function fn(callback: Callback): void { + callback(); +} + +let a: number = 0; +fn(() => { + a = 666 +}) + +arktest.assertEQ(a, 666) diff --git a/ets2panda/test/runtime/ets/lambdaParamsInfer2.ets b/ets2panda/test/runtime/ets/lambdaParamsInfer2.ets new file mode 100644 index 0000000000..bf4d01b4b9 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambdaParamsInfer2.ets @@ -0,0 +1,75 @@ +/* + * 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. + */ + +function fn(callback: (() => void) | ((n: number) => void) | ((n: number, n2: number) => void)): void { + callback(1, 2) +} + +// test for lambda as param. +let emptyArg: number = 0; +let oneArg: number = 0; +let twoArgs: number = 0; +fn(() => { emptyArg = emptyArg - 1; }) +fn((n:number) => { oneArg = oneArg + n; }) +fn((n:number, n2: number) => { twoArgs = twoArgs + n + n2; }) +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +// test for named function as param. +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +function foo() { emptyArg = emptyArg - 1; } +function foo1(n: number) { oneArg = oneArg + n; } +function foo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } +fn(foo); +fn(foo1); +fn(foo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +// test for class method and static class method as param +class A { + goo() { emptyArg = emptyArg - 1; } + goo1(n: number) { oneArg = oneArg + n; } + goo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } + + static zoo() { emptyArg = emptyArg - 1; } + static zoo1(n: number) { oneArg = oneArg + n; } + static zoo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } +} + +let a = new A(); +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +fn(a.goo); +fn(a.goo1); +fn(a.goo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +fn(A.zoo); +fn(A.zoo1); +fn(A.zoo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) diff --git a/ets2panda/test/runtime/ets/lambdaParamsInfer3.ets b/ets2panda/test/runtime/ets/lambdaParamsInfer3.ets new file mode 100644 index 0000000000..da55406541 --- /dev/null +++ b/ets2panda/test/runtime/ets/lambdaParamsInfer3.ets @@ -0,0 +1,76 @@ +/* + * 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. + */ + +type Callback = (() => void) | ((n: number) => void) | ((n: number, n2: number) => void) +function fn(callback: Callback): void { + callback(1, 2) +} + +// test for lambda as param. +let emptyArg: number = 0; +let oneArg: number = 0; +let twoArgs: number = 0; +fn(() => { emptyArg = emptyArg - 1; }) +fn((n:number) => { oneArg = oneArg + n; }) +fn((n:number, n2: number) => { twoArgs = twoArgs + n + n2; }) +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +// test for named function as param. +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +function foo() { emptyArg = emptyArg - 1; } +function foo1(n: number) { oneArg = oneArg + n; } +function foo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } +fn(foo); +fn(foo1); +fn(foo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +// test for class method and static class method as param +class A { + goo() { emptyArg = emptyArg - 1; } + goo1(n: number) { oneArg = oneArg + n; } + goo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } + + static zoo() { emptyArg = emptyArg - 1; } + static zoo1(n: number) { oneArg = oneArg + n; } + static zoo2(n:number, n2: number) { twoArgs = twoArgs + n + n2; } +} + +let a = new A(); +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +fn(a.goo); +fn(a.goo1); +fn(a.goo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) + +emptyArg = 0; +oneArg = 0; +twoArgs = 0; +fn(A.zoo); +fn(A.zoo1); +fn(A.zoo2); +arktest.assertEQ(emptyArg, -1) +arktest.assertEQ(oneArg, 1) +arktest.assertEQ(twoArgs, 3) diff --git a/ets2panda/util/helpers.cpp b/ets2panda/util/helpers.cpp index acc599db41..37b43e97a8 100644 --- a/ets2panda/util/helpers.cpp +++ b/ets2panda/util/helpers.cpp @@ -814,6 +814,24 @@ util::UString Helpers::EscapeHTMLString(ArenaAllocator *allocator, const std::st return replaced; } +ir::AstNode *Helpers::DerefETSTypeReference(ir::AstNode *node) +{ + ES2PANDA_ASSERT(node->IsETSTypeReference()); + do { + auto *name = node->AsETSTypeReference()->Part()->GetIdent(); + + ES2PANDA_ASSERT(name->IsIdentifier()); + auto *var = name->AsIdentifier()->Variable(); + ES2PANDA_ASSERT(var != nullptr); + auto *declNode = var->Declaration()->Node(); + if (!declNode->IsTSTypeAliasDeclaration()) { + return declNode; + } + node = declNode->AsTSTypeAliasDeclaration()->TypeAnnotation(); + } while (node->IsETSTypeReference()); + return node; +} + bool Helpers::IsAsyncMethod(ir::AstNode const *node) { if (!node->IsMethodDefinition()) { diff --git a/ets2panda/util/helpers.h b/ets2panda/util/helpers.h index f8255dc477..a1a7ed6cd7 100644 --- a/ets2panda/util/helpers.h +++ b/ets2panda/util/helpers.h @@ -207,6 +207,7 @@ public: checker::Type *const type); [[nodiscard]] static util::UString EscapeHTMLString(ArenaAllocator *allocator, const std::string &str); + [[nodiscard]] static ir::AstNode *DerefETSTypeReference(ir::AstNode *node); }; template -- Gitee From c0ceaf27dc0150ff21e1663723e95e30397bd475 Mon Sep 17 00:00:00 2001 From: ZhongNing Date: Mon, 7 Jul 2025 17:11:14 +0800 Subject: [PATCH 053/107] fix issue for arkts-builtin-cotr Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKE79 Test scenarios: new tests added to the linter Signed-off-by: ZhongNing --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 3 +++ ets2panda/linter/test/builtin/builtin_callsignature.ets | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..835491bd40 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -4352,6 +4352,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!this.options.arkts2) { return; } + if (ts.isCallExpression(tsCallExpr) && tsCallExpr.expression.kind === ts.SyntaxKind.SuperKeyword) { + return; + } const node = ts.isCallExpression(tsCallExpr) ? tsCallExpr.expression : tsCallExpr.typeName; const constructorType = this.tsTypeChecker.getTypeAtLocation(node); const callSignatures = constructorType.getCallSignatures(); diff --git a/ets2panda/linter/test/builtin/builtin_callsignature.ets b/ets2panda/linter/test/builtin/builtin_callsignature.ets index ccb7f4de95..c728c8dc6c 100644 --- a/ets2panda/linter/test/builtin/builtin_callsignature.ets +++ b/ets2panda/linter/test/builtin/builtin_callsignature.ets @@ -34,4 +34,10 @@ function anotherName(ctorName0: BigIntConstructor) { // ERROR type BigIntConstructor1 = BigIntConstructor; // ERROR let ctorName2:BigIntConstructor1 = ctorName1 // ERROR const rs2 = ctorName2(1); // ERROR +} + +class A extends Error { + constructor(str: string) { + super(str); + } } \ No newline at end of file -- Gitee From 242bd6b54df48bdb3915bcc35b356c24729f4afc Mon Sep 17 00:00:00 2001 From: ZhongNing Date: Mon, 7 Jul 2025 18:35:45 +0800 Subject: [PATCH 054/107] Fix for InterOpImportJs Issue:https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKDWN Test scenarios: fix bug Signed-off-by: ZhongNing --- .../linter/src/lib/autofixes/Autofixer.ts | 123 +++++++++++------- .../binary_operation_js_obj.ets.autofix.json | 4 +- .../binary_operation_js_obj.ets.migrate.ets | 7 +- .../binary_operation_js_obj.ets.migrate.json | 38 ++---- .../call_object_methods.ets.autofix.json | 2 +- .../call_object_methods.ets.migrate.ets | 3 +- .../call_object_methods.ets.migrate.json | 12 +- ...ncreases_decreases_js_obj.ets.autofix.json | 2 +- ...increases_decreases_js_obj.ets.migrate.ets | 3 +- ...ncreases_decreases_js_obj.ets.migrate.json | 28 ++-- .../instantiated_js_obj.ets.autofix.json | 2 +- .../instantiated_js_obj.ets.migrate.ets | 5 +- .../instantiated_js_obj.ets.migrate.json | 14 +- .../interop_convert_import.ets.autofix.json | 2 +- .../interop_convert_import.ets.migrate.ets | 15 +-- .../interop_convert_import.ets.migrate.json | 32 ++--- ...interop_equality_judgment.ets.autofix.json | 2 +- .../interop_equality_judgment.ets.migrate.ets | 5 +- ...interop_equality_judgment.ets.migrate.json | 14 +- .../linter/test/interop/interop_import_js.ets | 2 +- .../interop/interop_import_js.ets.arkts2.json | 2 +- .../interop_import_js.ets.autofix.json | 54 ++++---- .../interop/interop_import_js.ets.migrate.ets | 30 ++--- .../interop_import_js.ets.migrate.json | 82 ++---------- ...interop_import_js_compare.ets.autofix.json | 2 +- .../interop_import_js_compare.ets.migrate.ets | 7 +- ...interop_import_js_compare.ets.migrate.json | 22 +--- .../interop_import_js_index.ets.autofix.json | 4 +- .../interop_import_js_index.ets.migrate.ets | 6 +- .../interop_import_js_index.ets.migrate.json | 36 ++--- .../interop_import_js_rules.ets.autofix.json | 18 +-- .../interop_import_typeof_js.ets.autofix.json | 6 +- .../interop_import_typeof_js.ets.migrate.ets | 17 +-- .../interop_import_typeof_js.ets.migrate.json | 64 +++------ ..._not_have_property_arkts2.ets.autofix.json | 2 +- ...p_not_have_property_arkts2.ets.migrate.ets | 15 +-- ..._not_have_property_arkts2.ets.migrate.json | 88 ++++++------- ..._have_property_num_arkts2.ets.autofix.json | 2 +- ...t_have_property_num_arkts2.ets.migrate.ets | 3 +- ..._have_property_num_arkts2.ets.migrate.json | 34 ++--- .../no_await_js_promise.ets.autofix.json | 32 ++--- .../no_await_js_promise.ets.migrate.ets | 11 +- .../no_await_js_promise.ets.migrate.json | 66 ++++------ .../interop/no_js_instanceof.ets.autofix.json | 2 +- .../interop/no_js_instanceof.ets.migrate.ets | 13 +- .../interop/no_js_instanceof.ets.migrate.json | 32 ++--- .../unary_operation_js_obj.ets.autofix.json | 2 +- .../unary_operation_js_obj.ets.migrate.ets | 3 +- .../unary_operation_js_obj.ets.migrate.json | 24 +--- 49 files changed, 383 insertions(+), 611 deletions(-) diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index c3cab4c0e3..fbd69ec830 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -86,9 +86,6 @@ const GENERATED_DESTRUCT_OBJECT_TRESHOLD = 1000; const GENERATED_DESTRUCT_ARRAY_NAME = 'GeneratedDestructArray_'; const GENERATED_DESTRUCT_ARRAY_TRESHOLD = 1000; -const GENERATED_IMPORT_VARIABLE_NAME = 'GeneratedImportVar_'; -const GENERATED_IMPORT_VARIABLE_TRESHOLD = 1000; - const GENERATED_TMP_VARIABLE_NAME = 'tmp_'; const GENERATED_TMP_VARIABLE_TRESHOLD = 1000; @@ -151,17 +148,11 @@ export class Autofixer { GENERATED_OBJECT_LITERAL_INIT_INTERFACE_TRESHOLD ); - private readonly importVarNameGenerator = new NameGenerator( - GENERATED_IMPORT_VARIABLE_NAME, - GENERATED_IMPORT_VARIABLE_TRESHOLD - ); - private readonly tmpVariableNameGenerator = new NameGenerator( GENERATED_TMP_VARIABLE_NAME, GENERATED_TMP_VARIABLE_TRESHOLD ); - private modVarName: string = ''; private readonly lastImportEndMap = new Map(); private readonly symbolCache: SymbolCache; @@ -4208,27 +4199,19 @@ export class Autofixer { } private static createVariableForInteropImport( - newVarName: string, - interopObject: string, - interopMethod: string, - interopPropertyOrModule: string + interopProperty: string, + symbolName: string, + propertyName: string ): ts.VariableStatement { const newVarDecl = ts.factory.createVariableStatement( undefined, ts.factory.createVariableDeclarationList( [ ts.factory.createVariableDeclaration( - ts.factory.createIdentifier(newVarName), + ts.factory.createIdentifier(symbolName), undefined, undefined, - ts.factory.createCallExpression( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(interopObject), - ts.factory.createIdentifier(interopMethod) - ), - undefined, - [ts.factory.createStringLiteral(interopPropertyOrModule)] - ) + this.createVariableInitialForInteropImport(propertyName, interopProperty) ) ], ts.NodeFlags.Let @@ -4237,6 +4220,25 @@ export class Autofixer { return newVarDecl; } + private static createVariableInitialForInteropImport(propertyName: string, interopProperty: string): ts.Expression { + const initializer = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(ES_VALUE), + ts.factory.createIdentifier(LOAD) + ), + undefined, + [ts.factory.createStringLiteral(interopProperty)] + ), + ts.factory.createIdentifier(GET_PROPERTY) + ), + undefined, + [ts.factory.createStringLiteral(propertyName)] + ); + return initializer; + } + private static getOriginalNameAtSymbol(symbolName: string, symbol?: ts.Symbol): string { if (symbol) { const originalDeclaration = symbol.declarations?.[0]; @@ -4313,20 +4315,25 @@ export class Autofixer { defaultSymbol?: ts.Symbol ): Autofix[] | undefined { let statements: string[] = []; - statements = this.constructAndSaveimportDecl2Arrays(importDecl, moduleSpecifier, undefined, statements, true); if (importClause.name) { const symbolName = importClause.name.text; const originalName = Autofixer.getOriginalNameAtSymbol(symbolName, defaultSymbol); - statements = this.constructAndSaveimportDecl2Arrays(importDecl, symbolName, originalName, statements, false); + statements = this.constructAndSaveimportDecl2Arrays( + importDecl, + moduleSpecifier, + symbolName, + originalName, + statements + ); } const namedBindings = importClause.namedBindings; - if (namedBindings && ts.isNamedImports(namedBindings)) { - namedBindings.elements.map((element) => { - const symbolName = element.name.text; - const originalName = element.propertyName ? element.propertyName.text : symbolName; - statements = this.constructAndSaveimportDecl2Arrays(importDecl, symbolName, originalName, statements, false); - return statements; - }); + if (namedBindings) { + statements = this.getStatementForInterOpImportJsOnNamedBindings( + namedBindings, + importDecl, + moduleSpecifier, + statements + ); } if (statements.length <= 0) { return undefined; @@ -4346,30 +4353,48 @@ export class Autofixer { ]; } + private getStatementForInterOpImportJsOnNamedBindings( + namedBindings: ts.NamedImportBindings, + importDecl: ts.ImportDeclaration, + moduleSpecifier: string, + statements: string[] + ): string[] { + if (ts.isNamespaceImport(namedBindings)) { + const symbolName = namedBindings.name.text; + statements = this.constructAndSaveimportDecl2Arrays( + importDecl, + moduleSpecifier, + symbolName, + symbolName, + statements + ); + } + if (ts.isNamedImports(namedBindings)) { + namedBindings.elements.map((element) => { + const symbolName = element.name.text; + const originalName = element.propertyName ? element.propertyName.text : symbolName; + statements = this.constructAndSaveimportDecl2Arrays( + importDecl, + moduleSpecifier, + symbolName, + originalName, + statements + ); + return statements; + }); + } + return statements; + } + private constructAndSaveimportDecl2Arrays( importDecl: ts.ImportDeclaration, + moduleSpecifier: string, symbolName: string, originalName: string | undefined, - statements: string[], - isLoad: boolean + statements: string[] ): string[] { - if (isLoad) { - const newVarName = TsUtils.generateUniqueName(this.importVarNameGenerator, this.sourceFile); - if (!newVarName) { - return []; - } - this.modVarName = newVarName; - } const propertyName = originalName || symbolName; - const constructDeclInfo: string[] = isLoad ? - [this.modVarName, ES_VALUE, LOAD] : - [symbolName, this.modVarName, GET_PROPERTY]; - const newVarDecl = Autofixer.createVariableForInteropImport( - constructDeclInfo[0], - constructDeclInfo[1], - constructDeclInfo[2], - propertyName - ); + const newVarDecl = Autofixer.createVariableForInteropImport(moduleSpecifier, symbolName, propertyName); const text = this.printer.printNode(ts.EmitHint.Unspecified, newVarDecl, importDecl.getSourceFile()); statements.push(TsUtils.removeOrReplaceQuotes(text, true)); return statements; diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json index 796dfbb772..7795884ac2 100644 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.autofix.json @@ -13,7 +13,7 @@ "See the License for the specific language governing permissions and", "limitations under the License." ], -"result": [ + "result": [ { "line": 15, "column": 1, @@ -33,7 +33,7 @@ { "start": 656, "end": 656, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./binary_operation_js_obj_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\nlet m = GeneratedImportVar_1.getProperty('m');\nlet n = GeneratedImportVar_1.getProperty('n');\n", + "replacementText": "let foo = ESValue.load('./binary_operation_js_obj_js').getProperty('foo');\nlet m = ESValue.load('./binary_operation_js_obj_js').getProperty('m');\nlet n = ESValue.load('./binary_operation_js_obj_js').getProperty('n');\n", "line": 15, "column": 1, "endLine": 15, diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets index f71f2540b4..7a93ab3ecb 100644 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.ets @@ -12,10 +12,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./binary_operation_js_obj_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let m = GeneratedImportVar_1.getProperty('m'); -let n = GeneratedImportVar_1.getProperty('n'); +let foo = ESValue.load('./binary_operation_js_obj_js').getProperty('foo'); +let m = ESValue.load('./binary_operation_js_obj_js').getProperty('m'); +let n = ESValue.load('./binary_operation_js_obj_js').getProperty('n'); let a = foo.getProperty("a") let b = foo.getProperty("b") diff --git a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json index 00ccbc39c6..f0dfd04337 100644 --- a/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/binary_operation_js_obj.ets.migrate.json @@ -18,7 +18,7 @@ "line": 15, "column": 5, "endLine": 15, - "endColumn": 72, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 50, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,17 +38,17 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 46, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 18, + "line": 19, "column": 5, - "endLine": 18, - "endColumn": 46, + "endLine": 19, + "endColumn": 29, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -65,19 +65,9 @@ "severity": "ERROR" }, { - "line": 21, - "column": 5, - "endLine": 21, - "endColumn": 29, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 27, + "line": 26, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 15, "problem": "MathPow", "suggest": "", @@ -85,9 +75,9 @@ "severity": "ERROR" }, { - "line": 31, + "line": 30, "column": 1, - "endLine": 31, + "endLine": 30, "endColumn": 37, "problem": "MathPow", "suggest": "", @@ -95,9 +85,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 36, "column": 1, - "endLine": 37, + "endLine": 36, "endColumn": 15, "problem": "MathPow", "suggest": "", @@ -105,9 +95,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 48, "column": 1, - "endLine": 49, + "endLine": 48, "endColumn": 17, "problem": "MathPow", "suggest": "", diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json index ca67f37978..0168feead4 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 650, "end": 650, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./call_object_methods_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./call_object_methods_js').getProperty('foo');\n", "line": 15, "column": 1, "endLine": 15, diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets index 600a9cadac..e9e2087b58 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.ets @@ -12,8 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./call_object_methods_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); +let foo = ESValue.load('./call_object_methods_js').getProperty('foo'); foo.invokeMethod("bar", ESValue.wrap(123.0)) diff --git a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json index ccc6caf0a4..149a43f6f5 100644 --- a/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json +++ b/ets2panda/linter/test/interop/call_object_methods.ets.migrate.json @@ -18,17 +18,7 @@ "line": 15, "column": 5, "endLine": 15, - "endColumn": 68, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 50, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json index a0e63a21c5..f8d8a8cfdc 100644 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 655, "end": 655, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./increases_decreases_js_obj_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./increases_decreases_js_obj_js').getProperty('foo');\n", "line": 15, "column": 1, "endLine": 15, diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets index 276cf1196d..cf3c50c2c8 100644 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.ets @@ -12,8 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./increases_decreases_js_obj_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); +let foo = ESValue.load('./increases_decreases_js_obj_js').getProperty('foo'); let a: number =0.0 a = foo.getProperty("num").toNumber() diff --git a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json index 78b7199f4f..2d9436fba2 100644 --- a/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/increases_decreases_js_obj.ets.migrate.json @@ -18,26 +18,16 @@ "line": 15, "column": 5, "endLine": 15, - "endColumn": 75, + "endColumn": 77, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 16, + "line": 35, "column": 5, - "endLine": 16, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 5, - "endLine": 36, + "endLine": 35, "endColumn": 46, "problem": "AnyType", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 39, "column": 5, - "endLine": 40, + "endLine": 39, "endColumn": 46, "problem": "AnyType", "suggest": "", @@ -55,9 +45,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 43, "column": 5, - "endLine": 44, + "endLine": 43, "endColumn": 46, "problem": "AnyType", "suggest": "", @@ -65,9 +55,9 @@ "severity": "ERROR" }, { - "line": 48, + "line": 47, "column": 5, - "endLine": 48, + "endLine": 47, "endColumn": 46, "problem": "AnyType", "suggest": "", diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json index c0509f85ea..40daaaa99e 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 655, "end": 655, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./instantiated_js_obj_js');\nlet Foo = GeneratedImportVar_1.getProperty('Foo');\nlet Foo1 = GeneratedImportVar_1.getProperty('Foo1');\n", + "replacementText": "let Foo = ESValue.load('./instantiated_js_obj_js').getProperty('Foo');\nlet Foo1 = ESValue.load('./instantiated_js_obj_js').getProperty('Foo1');\n", "line": 16, "column": 1, "endLine": 16, diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets index 754fa9a041..9f8564ec60 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.ets @@ -13,9 +13,8 @@ * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./instantiated_js_obj_js'); -let Foo = GeneratedImportVar_1.getProperty('Foo'); -let Foo1 = GeneratedImportVar_1.getProperty('Foo1'); +let Foo = ESValue.load('./instantiated_js_obj_js').getProperty('Foo'); +let Foo1 = ESValue.load('./instantiated_js_obj_js').getProperty('Foo1'); class A { num: number = 1.0; diff --git a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json index 5c043e26be..a1be17f7a4 100644 --- a/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/instantiated_js_obj.ets.migrate.json @@ -18,7 +18,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 68, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,17 +28,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 52, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json b/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json index f2a8c5c3a4..728ef37abc 100644 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.autofix.json @@ -43,7 +43,7 @@ { "start": 740, "end": 740, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_convert_import_js.js');\r\nlet foo = GeneratedImportVar_1.getProperty('foo');\r\nlet foo2 = GeneratedImportVar_1.getProperty('foo2');\r\nlet foo3 = GeneratedImportVar_1.getProperty('foo3');\r\nlet foo4 = GeneratedImportVar_1.getProperty('foo4');\r\nlet array_val = GeneratedImportVar_1.getProperty('array_val');\r\nlet null_val = GeneratedImportVar_1.getProperty('null_val');\r\nlet undefined_val = GeneratedImportVar_1.getProperty('undefined_val');\r\n", + "replacementText": "let foo = ESValue.load('./interop_convert_import_js.js').getProperty('foo');\r\nlet foo2 = ESValue.load('./interop_convert_import_js.js').getProperty('foo2');\r\nlet foo3 = ESValue.load('./interop_convert_import_js.js').getProperty('foo3');\r\nlet foo4 = ESValue.load('./interop_convert_import_js.js').getProperty('foo4');\r\nlet array_val = ESValue.load('./interop_convert_import_js.js').getProperty('array_val');\r\nlet null_val = ESValue.load('./interop_convert_import_js.js').getProperty('null_val');\r\nlet undefined_val = ESValue.load('./interop_convert_import_js.js').getProperty('undefined_val');\r\n", "line": 17, "column": 2, "endLine": 17, diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets index 2c49f3dc58..b90e38880f 100644 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.ets @@ -14,14 +14,13 @@ */ 'use static' - let GeneratedImportVar_1 = ESValue.load('./interop_convert_import_js.js'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let foo2 = GeneratedImportVar_1.getProperty('foo2'); -let foo3 = GeneratedImportVar_1.getProperty('foo3'); -let foo4 = GeneratedImportVar_1.getProperty('foo4'); -let array_val = GeneratedImportVar_1.getProperty('array_val'); -let null_val = GeneratedImportVar_1.getProperty('null_val'); -let undefined_val = GeneratedImportVar_1.getProperty('undefined_val'); + let foo = ESValue.load('./interop_convert_import_js.js').getProperty('foo'); +let foo2 = ESValue.load('./interop_convert_import_js.js').getProperty('foo2'); +let foo3 = ESValue.load('./interop_convert_import_js.js').getProperty('foo3'); +let foo4 = ESValue.load('./interop_convert_import_js.js').getProperty('foo4'); +let array_val = ESValue.load('./interop_convert_import_js.js').getProperty('array_val'); +let null_val = ESValue.load('./interop_convert_import_js.js').getProperty('null_val'); +let undefined_val = ESValue.load('./interop_convert_import_js.js').getProperty('undefined_val'); let a: number = foo.getProperty("num").toNumber() diff --git a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json index 52e07c8a2b..e2860e2725 100644 --- a/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_convert_import.ets.migrate.json @@ -18,7 +18,7 @@ "line": 17, "column": 6, "endLine": 17, - "endColumn": 75, + "endColumn": 77, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 50, + "endColumn": 78, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 52, + "endColumn": 78, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,7 +48,7 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 52, + "endColumn": 78, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,7 +58,7 @@ "line": 21, "column": 5, "endLine": 21, - "endColumn": 52, + "endColumn": 88, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -68,7 +68,7 @@ "line": 22, "column": 5, "endLine": 22, - "endColumn": 62, + "endColumn": 86, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -78,26 +78,16 @@ "line": 23, "column": 5, "endLine": 23, - "endColumn": 60, + "endColumn": 96, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 24, - "column": 5, - "endLine": 24, - "endColumn": 70, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 33, + "line": 32, "column": 44, - "endLine": 33, + "endLine": 32, "endColumn": 68, "problem": "GenericCallNoTypeArgs", "suggest": "", @@ -105,9 +95,9 @@ "severity": "ERROR" }, { - "line": 43, + "line": 42, "column": 8, - "endLine": 43, + "endLine": 42, "endColumn": 24, "problem": "InterOpConvertImport", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json index 3f22cfc7bf..d38814d67c 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 656, "end": 656, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_equality_judgment_js');\nlet a = GeneratedImportVar_1.getProperty('a');\nlet b = GeneratedImportVar_1.getProperty('b');\n", + "replacementText": "let a = ESValue.load('./interop_equality_judgment_js').getProperty('a');\nlet b = ESValue.load('./interop_equality_judgment_js').getProperty('b');\n", "line": 16, "column": 1, "endLine": 16, diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets index 9a2c6e2cab..75dfa93e70 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.ets @@ -13,9 +13,8 @@ * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./interop_equality_judgment_js'); -let a = GeneratedImportVar_1.getProperty('a'); -let b = GeneratedImportVar_1.getProperty('b'); +let a = ESValue.load('./interop_equality_judgment_js').getProperty('a'); +let b = ESValue.load('./interop_equality_judgment_js').getProperty('b'); a.areEqual(b) !a.areEqual(b) diff --git a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json index 38e88ae0b6..c8a37393a6 100644 --- a/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_equality_judgment.ets.migrate.json @@ -18,7 +18,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 74, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,17 +28,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 46, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 46, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", diff --git a/ets2panda/linter/test/interop/interop_import_js.ets b/ets2panda/linter/test/interop/interop_import_js.ets index 337d1600c6..a4c0b8fea6 100644 --- a/ets2panda/linter/test/interop/interop_import_js.ets +++ b/ets2panda/linter/test/interop/interop_import_js.ets @@ -18,5 +18,5 @@ import { fjs } from '../main/js_lib'; import { CPreview,bar,foo } from "./jsfiles/preview_import_js"; import myAaa from "./interop_import_js_js"; import myAaa,{ClassA,Dog} from "./interop_import_js_js"; -import * as namespace from "./interop_import_js_js"; +import * as tjs from "./interop_import_js_js"; import { Wiki, Dog as Doge } from './interop_import_js_js' \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json index 7d56ee5afd..f8dbfb7b6c 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.arkts2.json @@ -68,7 +68,7 @@ "line": 21, "column": 1, "endLine": 21, - "endColumn": 53, + "endColumn": 47, "problem": "InterOpImportJs", "suggest": "", "rule": "Importing directly from \"JS\" module is not supported (arkts-interop-js2s-import-js)", diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json index 2a3dec941a..95ff8c7ad1 100755 --- a/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.autofix.json @@ -31,9 +31,9 @@ "endColumn": 38 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('../main/js_lib');\nlet Cjs = GeneratedImportVar_1.getProperty('Cjs');\n", + "start": 952, + "end": 952, + "replacementText": "let Cjs = ESValue.load('../main/js_lib').getProperty('Cjs');\n", "line": 16, "column": 1, "endLine": 16, @@ -61,9 +61,9 @@ "endColumn": 38 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_2 = ESValue.load('../main/js_lib');\nlet fjs = GeneratedImportVar_2.getProperty('fjs');\n", + "start": 952, + "end": 952, + "replacementText": "let fjs = ESValue.load('../main/js_lib').getProperty('fjs');\n", "line": 17, "column": 1, "endLine": 17, @@ -91,9 +91,9 @@ "endColumn": 64 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_3 = ESValue.load('./jsfiles/preview_import_js');\nlet CPreview = GeneratedImportVar_3.getProperty('CPreview');\nlet bar = GeneratedImportVar_3.getProperty('bar');\nlet foo = GeneratedImportVar_3.getProperty('foo');\n", + "start": 952, + "end": 952, + "replacementText": "let CPreview = ESValue.load('./jsfiles/preview_import_js').getProperty('CPreview');\nlet bar = ESValue.load('./jsfiles/preview_import_js').getProperty('bar');\nlet foo = ESValue.load('./jsfiles/preview_import_js').getProperty('foo');\n", "line": 18, "column": 1, "endLine": 18, @@ -121,9 +121,9 @@ "endColumn": 44 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_4 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_4.getProperty('aaa');\n", + "start": 952, + "end": 952, + "replacementText": "let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa');\n", "line": 19, "column": 1, "endLine": 19, @@ -151,9 +151,9 @@ "endColumn": 57 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_5 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_5.getProperty('aaa');\nlet ClassA = GeneratedImportVar_5.getProperty('ClassA');\nlet Dog = GeneratedImportVar_5.getProperty('Dog');\n", + "start": 952, + "end": 952, + "replacementText": "let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa');\nlet ClassA = ESValue.load('./interop_import_js_js').getProperty('ClassA');\nlet Dog = ESValue.load('./interop_import_js_js').getProperty('Dog');\n", "line": 20, "column": 1, "endLine": 20, @@ -168,26 +168,26 @@ "line": 21, "column": 1, "endLine": 21, - "endColumn": 53, + "endColumn": 47, "problem": "InterOpImportJs", "autofix": [ { "start": 847, - "end": 899, + "end": 893, "replacementText": "", "line": 21, "column": 1, "endLine": 21, - "endColumn": 53 + "endColumn": 47 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_6 = ESValue.load('./interop_import_js_js');\n", + "start": 952, + "end": 952, + "replacementText": "let tjs = ESValue.load('./interop_import_js_js').getProperty('tjs');\n", "line": 21, "column": 1, "endLine": 21, - "endColumn": 53 + "endColumn": 47 } ], "suggest": "", @@ -202,8 +202,8 @@ "problem": "InterOpImportJs", "autofix": [ { - "start": 900, - "end": 958, + "start": 894, + "end": 952, "replacementText": "", "line": 22, "column": 1, @@ -211,9 +211,9 @@ "endColumn": 59 }, { - "start": 958, - "end": 958, - "replacementText": "let GeneratedImportVar_7 = ESValue.load('./interop_import_js_js');\nlet Wiki = GeneratedImportVar_7.getProperty('Wiki');\nlet Doge = GeneratedImportVar_7.getProperty('Dog');\n", + "start": 952, + "end": 952, + "replacementText": "let Wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki');\nlet Doge = ESValue.load('./interop_import_js_js').getProperty('Dog');\n", "line": 22, "column": 1, "endLine": 22, diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets index 851b32fdc0..4ac9329ef8 100644 --- a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.ets @@ -19,21 +19,15 @@ -let GeneratedImportVar_7 = ESValue.load('./interop_import_js_js'); -let Wiki = GeneratedImportVar_7.getProperty('Wiki'); -let Doge = GeneratedImportVar_7.getProperty('Dog'); -let GeneratedImportVar_6 = ESValue.load('./interop_import_js_js'); -let GeneratedImportVar_5 = ESValue.load('./interop_import_js_js'); -let myAaa = GeneratedImportVar_5.getProperty('aaa'); -let ClassA = GeneratedImportVar_5.getProperty('ClassA'); -let Dog = GeneratedImportVar_5.getProperty('Dog'); -let GeneratedImportVar_4 = ESValue.load('./interop_import_js_js'); -let myAaa = GeneratedImportVar_4.getProperty('aaa'); -let GeneratedImportVar_3 = ESValue.load('./jsfiles/preview_import_js'); -let CPreview = GeneratedImportVar_3.getProperty('CPreview'); -let bar = GeneratedImportVar_3.getProperty('bar'); -let foo = GeneratedImportVar_3.getProperty('foo'); -let GeneratedImportVar_2 = ESValue.load('../main/js_lib'); -let fjs = GeneratedImportVar_2.getProperty('fjs'); -let GeneratedImportVar_1 = ESValue.load('../main/js_lib'); -let Cjs = GeneratedImportVar_1.getProperty('Cjs'); +let Wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki'); +let Doge = ESValue.load('./interop_import_js_js').getProperty('Dog'); +let tjs = ESValue.load('./interop_import_js_js').getProperty('tjs'); +let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa'); +let ClassA = ESValue.load('./interop_import_js_js').getProperty('ClassA'); +let Dog = ESValue.load('./interop_import_js_js').getProperty('Dog'); +let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa'); +let CPreview = ESValue.load('./jsfiles/preview_import_js').getProperty('CPreview'); +let bar = ESValue.load('./jsfiles/preview_import_js').getProperty('bar'); +let foo = ESValue.load('./jsfiles/preview_import_js').getProperty('foo'); +let fjs = ESValue.load('../main/js_lib').getProperty('fjs'); +let Cjs = ESValue.load('../main/js_lib').getProperty('Cjs'); diff --git a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json index d46fff44ee..b401dd1af6 100644 --- a/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_js.ets.migrate.json @@ -18,7 +18,7 @@ "line": 22, "column": 5, "endLine": 22, - "endColumn": 66, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 23, "column": 5, "endLine": 23, - "endColumn": 52, + "endColumn": 69, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 24, "column": 5, "endLine": 24, - "endColumn": 51, + "endColumn": 68, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,7 +48,7 @@ "line": 25, "column": 5, "endLine": 25, - "endColumn": 66, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,7 +58,7 @@ "line": 26, "column": 5, "endLine": 26, - "endColumn": 66, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -68,7 +68,7 @@ "line": 27, "column": 5, "endLine": 27, - "endColumn": 52, + "endColumn": 68, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -78,7 +78,7 @@ "line": 28, "column": 5, "endLine": 28, - "endColumn": 56, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -88,7 +88,7 @@ "line": 29, "column": 5, "endLine": 29, - "endColumn": 50, + "endColumn": 83, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -98,7 +98,7 @@ "line": 30, "column": 5, "endLine": 30, - "endColumn": 66, + "endColumn": 73, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -108,7 +108,7 @@ "line": 31, "column": 5, "endLine": 31, - "endColumn": 52, + "endColumn": 73, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -118,7 +118,7 @@ "line": 32, "column": 5, "endLine": 32, - "endColumn": 71, + "endColumn": 60, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -133,66 +133,6 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" - }, - { - "line": 34, - "column": 5, - "endLine": 34, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 35, - "column": 5, - "endLine": 35, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 36, - "column": 5, - "endLine": 36, - "endColumn": 58, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 37, - "column": 5, - "endLine": 37, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 38, - "column": 5, - "endLine": 38, - "endColumn": 58, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 39, - "column": 5, - "endLine": 39, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json index baf465561b..069c2730b0 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 663, "end": 663, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_compare_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\nlet m = GeneratedImportVar_1.getProperty('m');\nlet n = GeneratedImportVar_1.getProperty('n');\n", + "replacementText": "let foo = ESValue.load('./interop_import_js_compare_js').getProperty('foo');\nlet m = ESValue.load('./interop_import_js_compare_js').getProperty('m');\nlet n = ESValue.load('./interop_import_js_compare_js').getProperty('n');\n", "line": 17, "column": 1, "endLine": 17, diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets index 3e99265ba8..a95b861772 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.ets @@ -14,10 +14,9 @@ */ -let GeneratedImportVar_1 = ESValue.load('./interop_import_js_compare_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let m = GeneratedImportVar_1.getProperty('m'); -let n = GeneratedImportVar_1.getProperty('n'); +let foo = ESValue.load('./interop_import_js_compare_js').getProperty('foo'); +let m = ESValue.load('./interop_import_js_compare_js').getProperty('m'); +let n = ESValue.load('./interop_import_js_compare_js').getProperty('n'); let a = foo.getProperty("a") let b = foo.getProperty("b") diff --git a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json index 680e681f88..b425bd1e5a 100644 --- a/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_js_compare.ets.migrate.json @@ -18,7 +18,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 74, + "endColumn": 76, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 50, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,17 +38,17 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 46, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 20, + "line": 21, "column": 5, - "endLine": 20, - "endColumn": 46, + "endLine": 21, + "endColumn": 29, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -63,16 +63,6 @@ "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" - }, - { - "line": 23, - "column": 5, - "endLine": 23, - "endColumn": 29, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" } ] } \ No newline at end of file diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json index 7e7407ab2d..8b38c2c03f 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 703, "end": 703, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_rules_js');\nlet ff3 = GeneratedImportVar_1.getProperty('ff3');\n", + "replacementText": "let ff3 = ESValue.load('./interop_import_js_rules_js').getProperty('ff3');\n", "line": 15, "column": 1, "endLine": 15, @@ -63,7 +63,7 @@ { "start": 703, "end": 703, - "replacementText": "let GeneratedImportVar_2 = ESValue.load('./interop_import_js_index_js');\nlet foo = GeneratedImportVar_2.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./interop_import_js_index_js').getProperty('foo');\n", "line": 16, "column": 1, "endLine": 16, diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets index d26adb726f..7cac462bbc 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.ets @@ -13,10 +13,8 @@ * limitations under the License. */ -let GeneratedImportVar_2 = ESValue.load('./interop_import_js_index_js'); -let foo = GeneratedImportVar_2.getProperty('foo'); -let GeneratedImportVar_1 = ESValue.load('./interop_import_js_rules_js'); -let ff3 = GeneratedImportVar_1.getProperty('ff3'); +let foo = ESValue.load('./interop_import_js_index_js').getProperty('foo'); +let ff3 = ESValue.load('./interop_import_js_rules_js').getProperty('ff3'); let arr = foo.getProperty("arr") arr.getProperty(1.0) diff --git a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json index f816c83809..bc80aa171a 100644 --- a/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_js_index.ets.migrate.json @@ -18,7 +18,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 72, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,17 +28,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 18, - "column": 5, - "endLine": 18, - "endColumn": 72, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,16 +38,6 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 21, - "column": 5, - "endLine": 21, "endColumn": 33, "problem": "AnyType", "suggest": "", @@ -65,9 +45,9 @@ "severity": "ERROR" }, { - "line": 25, + "line": 23, "column": 5, - "endLine": 25, + "endLine": 23, "endColumn": 34, "problem": "AnyType", "suggest": "", @@ -75,9 +55,9 @@ "severity": "ERROR" }, { - "line": 29, + "line": 27, "column": 9, - "endLine": 29, + "endLine": 27, "endColumn": 43, "problem": "AnyType", "suggest": "", @@ -85,9 +65,9 @@ "severity": "ERROR" }, { - "line": 35, + "line": 33, "column": 10, - "endLine": 35, + "endLine": 33, "endColumn": 17, "problem": "AnyType", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json index 58320d2ba5..e160d4c3d0 100644 --- a/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_js_rules.ets.autofix.json @@ -43,7 +43,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_rules_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./interop_import_js_rules_js').getProperty('foo');\n", "line": 17, "column": 1, "endLine": 17, @@ -83,7 +83,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_2 = ESValue.load('./interop_import_js_rules_js');\nlet ff1 = GeneratedImportVar_2.getProperty('ff1');\nlet ff2 = GeneratedImportVar_2.getProperty('ff2');\n", + "replacementText": "let ff1 = ESValue.load('./interop_import_js_rules_js').getProperty('ff1');\nlet ff2 = ESValue.load('./interop_import_js_rules_js').getProperty('ff2');\n", "line": 18, "column": 1, "endLine": 18, @@ -123,7 +123,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_3 = ESValue.load('./interop_import_js_rules_js');\nlet A = GeneratedImportVar_3.getProperty('A');\n", + "replacementText": "let A = ESValue.load('./interop_import_js_rules_js').getProperty('A');\n", "line": 20, "column": 1, "endLine": 20, @@ -163,7 +163,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_4 = ESValue.load('./interop_import_js_rules_js');\nlet C = GeneratedImportVar_4.getProperty('C');\n", + "replacementText": "let C = ESValue.load('./interop_import_js_rules_js').getProperty('C');\n", "line": 21, "column": 1, "endLine": 21, @@ -203,7 +203,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_5 = ESValue.load('./interop_import_js_rules_js');\nlet ff3 = GeneratedImportVar_5.getProperty('ff3');\n", + "replacementText": "let ff3 = ESValue.load('./interop_import_js_rules_js').getProperty('ff3');\n", "line": 23, "column": 1, "endLine": 23, @@ -243,7 +243,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_6 = ESValue.load('./interop_import_js_rules_js');\nlet ff4 = GeneratedImportVar_6.getProperty('ff4');\n", + "replacementText": "let ff4 = ESValue.load('./interop_import_js_rules_js').getProperty('ff4');\n", "line": 25, "column": 1, "endLine": 25, @@ -283,7 +283,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_7 = ESValue.load('./interop_import_js_rules_js');\nlet handle = GeneratedImportVar_7.getProperty('handle');\n", + "replacementText": "let handle = ESValue.load('./interop_import_js_rules_js').getProperty('handle');\n", "line": 27, "column": 1, "endLine": 27, @@ -323,7 +323,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_8 = ESValue.load('./interop_import_js_rules_js');\nlet expand = GeneratedImportVar_8.getProperty('expand');\n", + "replacementText": "let expand = ESValue.load('./interop_import_js_rules_js').getProperty('expand');\n", "line": 29, "column": 1, "endLine": 29, @@ -363,7 +363,7 @@ { "start": 1092, "end": 1092, - "replacementText": "let GeneratedImportVar_9 = ESValue.load('./interop_import_js_rules_js');\nlet orange = GeneratedImportVar_9.getProperty('orange');\n", + "replacementText": "let orange = ESValue.load('./interop_import_js_rules_js').getProperty('orange');\n", "line": 30, "column": 1, "endLine": 30, diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json index 9481ffc18a..cfe6324f31 100644 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 783, "end": 783, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_import_js_js');\nlet myAaa = GeneratedImportVar_1.getProperty('aaa');\nlet ClassA = GeneratedImportVar_1.getProperty('ClassA');\nlet Dog = GeneratedImportVar_1.getProperty('Dog');\nlet Person = GeneratedImportVar_1.getProperty('Person');\nlet Wiki = GeneratedImportVar_1.getProperty('Wiki');\n", + "replacementText": "let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa');\nlet ClassA = ESValue.load('./interop_import_js_js').getProperty('ClassA');\nlet Dog = ESValue.load('./interop_import_js_js').getProperty('Dog');\nlet Person = ESValue.load('./interop_import_js_js').getProperty('Person');\nlet Wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki');\n", "line": 16, "column": 1, "endLine": 16, @@ -63,7 +63,7 @@ { "start": 783, "end": 783, - "replacementText": "let GeneratedImportVar_2 = ESValue.load('./interop_import_js_js');\nlet Doge = GeneratedImportVar_2.getProperty('Dog');\n", + "replacementText": "let Doge = ESValue.load('./interop_import_js_js').getProperty('Dog');\n", "line": 17, "column": 1, "endLine": 17, @@ -93,7 +93,7 @@ { "start": 783, "end": 783, - "replacementText": "let GeneratedImportVar_3 = ESValue.load('./interop_import_js_js');\nlet wiki = GeneratedImportVar_3.getProperty('Wiki');\n", + "replacementText": "let wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki');\n", "line": 18, "column": 1, "endLine": 18, diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets index ec79bd0e7e..f7cde32163 100644 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.ets @@ -15,16 +15,13 @@ -let GeneratedImportVar_3 = ESValue.load('./interop_import_js_js'); -let wiki = GeneratedImportVar_3.getProperty('Wiki'); -let GeneratedImportVar_2 = ESValue.load('./interop_import_js_js'); -let Doge = GeneratedImportVar_2.getProperty('Dog'); -let GeneratedImportVar_1 = ESValue.load('./interop_import_js_js'); -let myAaa = GeneratedImportVar_1.getProperty('aaa'); -let ClassA = GeneratedImportVar_1.getProperty('ClassA'); -let Dog = GeneratedImportVar_1.getProperty('Dog'); -let Person = GeneratedImportVar_1.getProperty('Person'); -let Wiki = GeneratedImportVar_1.getProperty('Wiki'); +let wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki'); +let Doge = ESValue.load('./interop_import_js_js').getProperty('Dog'); +let myAaa = ESValue.load('./interop_import_js_js').getProperty('aaa'); +let ClassA = ESValue.load('./interop_import_js_js').getProperty('ClassA'); +let Dog = ESValue.load('./interop_import_js_js').getProperty('Dog'); +let Person = ESValue.load('./interop_import_js_js').getProperty('Person'); +let Wiki = ESValue.load('./interop_import_js_js').getProperty('Wiki'); myAaa.invoke().typeOf(); //error diff --git a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json index af67e13229..fadac292b1 100644 --- a/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_import_typeof_js.ets.migrate.json @@ -18,7 +18,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 66, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 52, + "endColumn": 69, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 66, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,7 +48,7 @@ "line": 21, "column": 5, "endLine": 21, - "endColumn": 51, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,7 +58,7 @@ "line": 22, "column": 5, "endLine": 22, - "endColumn": 66, + "endColumn": 68, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -68,7 +68,7 @@ "line": 23, "column": 5, "endLine": 23, - "endColumn": 52, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -78,46 +78,16 @@ "line": 24, "column": 5, "endLine": 24, - "endColumn": 56, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 25, + "line": 28, "column": 5, - "endLine": 25, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 26, - "column": 5, - "endLine": 26, - "endColumn": 56, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 27, - "column": 5, - "endLine": 27, - "endColumn": 52, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 31, - "column": 5, - "endLine": 31, + "endLine": 28, "endColumn": 25, "problem": "AnyType", "suggest": "", @@ -125,9 +95,9 @@ "severity": "ERROR" }, { - "line": 39, + "line": 36, "column": 5, - "endLine": 39, + "endLine": 36, "endColumn": 35, "problem": "AnyType", "suggest": "", @@ -135,9 +105,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 42, "column": 5, - "endLine": 45, + "endLine": 42, "endColumn": 37, "problem": "AnyType", "suggest": "", @@ -145,9 +115,9 @@ "severity": "ERROR" }, { - "line": 46, + "line": 43, "column": 5, - "endLine": 46, + "endLine": 43, "endColumn": 42, "problem": "AnyType", "suggest": "", @@ -155,9 +125,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 56, "column": 7, - "endLine": 59, + "endLine": 56, "endColumn": 13, "problem": "InvalidIdentifier", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json index f2e4507626..a4046013b9 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.autofix.json @@ -43,7 +43,7 @@ { "start": 723, "end": 723, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_not_have_property_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\nlet person = GeneratedImportVar_1.getProperty('person');\nlet TestHelper = GeneratedImportVar_1.getProperty('TestHelper');\nlet Machine = GeneratedImportVar_1.getProperty('Machine');\nlet User = GeneratedImportVar_1.getProperty('User');\nlet Person = GeneratedImportVar_1.getProperty('Person');\nlet Employee = GeneratedImportVar_1.getProperty('Employee');\n", + "replacementText": "let foo = ESValue.load('./interop_not_have_property_js').getProperty('foo');\nlet person = ESValue.load('./interop_not_have_property_js').getProperty('person');\nlet TestHelper = ESValue.load('./interop_not_have_property_js').getProperty('TestHelper');\nlet Machine = ESValue.load('./interop_not_have_property_js').getProperty('Machine');\nlet User = ESValue.load('./interop_not_have_property_js').getProperty('User');\nlet Person = ESValue.load('./interop_not_have_property_js').getProperty('Person');\nlet Employee = ESValue.load('./interop_not_have_property_js').getProperty('Employee');\n", "line": 17, "column": 1, "endLine": 17, diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets index ff4cf81936..3a19e5d151 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.ets @@ -14,14 +14,13 @@ */ 'use static' -let GeneratedImportVar_1 = ESValue.load('./interop_not_have_property_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let person = GeneratedImportVar_1.getProperty('person'); -let TestHelper = GeneratedImportVar_1.getProperty('TestHelper'); -let Machine = GeneratedImportVar_1.getProperty('Machine'); -let User = GeneratedImportVar_1.getProperty('User'); -let Person = GeneratedImportVar_1.getProperty('Person'); -let Employee = GeneratedImportVar_1.getProperty('Employee'); +let foo = ESValue.load('./interop_not_have_property_js').getProperty('foo'); +let person = ESValue.load('./interop_not_have_property_js').getProperty('person'); +let TestHelper = ESValue.load('./interop_not_have_property_js').getProperty('TestHelper'); +let Machine = ESValue.load('./interop_not_have_property_js').getProperty('Machine'); +let User = ESValue.load('./interop_not_have_property_js').getProperty('User'); +let Person = ESValue.load('./interop_not_have_property_js').getProperty('Person'); +let Employee = ESValue.load('./interop_not_have_property_js').getProperty('Employee'); foo.getProperty("name") diff --git a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json index 258a8601a0..b8e566357c 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_arkts2.ets.migrate.json @@ -18,7 +18,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 74, + "endColumn": 76, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 50, + "endColumn": 82, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 56, + "endColumn": 90, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,7 +48,7 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 64, + "endColumn": 84, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,7 +58,7 @@ "line": 21, "column": 5, "endLine": 21, - "endColumn": 58, + "endColumn": 78, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -68,7 +68,7 @@ "line": 22, "column": 5, "endLine": 22, - "endColumn": 52, + "endColumn": 82, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -78,26 +78,16 @@ "line": 23, "column": 5, "endLine": 23, - "endColumn": 56, + "endColumn": 86, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 24, + "line": 33, "column": 5, - "endLine": 24, - "endColumn": 60, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 34, - "column": 5, - "endLine": 34, + "endLine": 33, "endColumn": 26, "problem": "AnyType", "suggest": "", @@ -105,9 +95,9 @@ "severity": "ERROR" }, { - "line": 37, + "line": 36, "column": 5, - "endLine": 37, + "endLine": 36, "endColumn": 85, "problem": "AnyType", "suggest": "", @@ -115,9 +105,9 @@ "severity": "ERROR" }, { - "line": 39, + "line": 38, "column": 9, - "endLine": 39, + "endLine": 38, "endColumn": 32, "problem": "AnyType", "suggest": "", @@ -125,9 +115,9 @@ "severity": "ERROR" }, { - "line": 39, + "line": 38, "column": 23, - "endLine": 39, + "endLine": 38, "endColumn": 30, "problem": "DynamicCtorCall", "suggest": "", @@ -135,9 +125,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 43, "column": 9, - "endLine": 44, + "endLine": 43, "endColumn": 31, "problem": "AnyType", "suggest": "", @@ -145,9 +135,9 @@ "severity": "ERROR" }, { - "line": 44, + "line": 43, "column": 20, - "endLine": 44, + "endLine": 43, "endColumn": 24, "problem": "DynamicCtorCall", "suggest": "", @@ -155,9 +145,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 48, "column": 5, - "endLine": 49, + "endLine": 48, "endColumn": 26, "problem": "AnyType", "suggest": "", @@ -165,9 +155,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 48, "column": 16, - "endLine": 49, + "endLine": 48, "endColumn": 20, "problem": "DynamicCtorCall", "suggest": "", @@ -175,9 +165,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 53, "column": 9, - "endLine": 54, + "endLine": 53, "endColumn": 30, "problem": "AnyType", "suggest": "", @@ -185,9 +175,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 53, "column": 20, - "endLine": 54, + "endLine": 53, "endColumn": 24, "problem": "DynamicCtorCall", "suggest": "", @@ -195,9 +185,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 58, "column": 9, - "endLine": 59, + "endLine": 58, "endColumn": 30, "problem": "AnyType", "suggest": "", @@ -205,9 +195,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 58, "column": 20, - "endLine": 59, + "endLine": 58, "endColumn": 24, "problem": "DynamicCtorCall", "suggest": "", @@ -215,9 +205,9 @@ "severity": "ERROR" }, { - "line": 64, + "line": 63, "column": 9, - "endLine": 64, + "endLine": 63, "endColumn": 43, "problem": "AnyType", "suggest": "", @@ -225,9 +215,9 @@ "severity": "ERROR" }, { - "line": 64, + "line": 63, "column": 23, - "endLine": 64, + "endLine": 63, "endColumn": 29, "problem": "DynamicCtorCall", "suggest": "", @@ -235,9 +225,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 68, "column": 9, - "endLine": 69, + "endLine": 68, "endColumn": 34, "problem": "AnyType", "suggest": "", @@ -245,9 +235,9 @@ "severity": "ERROR" }, { - "line": 69, + "line": 68, "column": 24, - "endLine": 69, + "endLine": 68, "endColumn": 32, "problem": "DynamicCtorCall", "suggest": "", diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json index 402aa07005..e2cc9e5d4c 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 650, "end": 650, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./interop_property_num_js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./interop_property_num_js').getProperty('foo');\n", "line": 16, "column": 1, "endLine": 16, diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets index 97d25fc238..b67f968b21 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.ets @@ -13,8 +13,7 @@ * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./interop_property_num_js'); -let foo = GeneratedImportVar_1.getProperty('foo'); +let foo = ESValue.load('./interop_property_num_js').getProperty('foo'); +foo.getProperty("num").toNumber(); diff --git a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json index 9ada1a9ba2..5c300a0f06 100644 --- a/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json +++ b/ets2panda/linter/test/interop/interop_not_have_property_num_arkts2.ets.migrate.json @@ -18,20 +18,20 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 69, + "endColumn": 71, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 17, - "column": 5, - "endLine": 17, - "endColumn": 50, - "problem": "AnyType", + "line": 19, + "column": 1, + "endLine": 19, + "endColumn": 35, + "problem": "UnaryArithmNotNumber", "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", + "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", "severity": "ERROR" }, { @@ -45,9 +45,9 @@ "severity": "ERROR" }, { - "line": 21, + "line": 22, "column": 1, - "endLine": 21, + "endLine": 22, "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", @@ -58,7 +58,7 @@ "line": 23, "column": 1, "endLine": 23, - "endColumn": 35, + "endColumn": 37, "problem": "UnaryArithmNotNumber", "suggest": "", "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", @@ -75,19 +75,9 @@ "severity": "ERROR" }, { - "line": 25, - "column": 1, - "endLine": 25, - "endColumn": 37, - "problem": "UnaryArithmNotNumber", - "suggest": "", - "rule": "Unary operators \"+\", \"-\" and \"~\" work only on numbers (arkts-no-polymorphic-unops)", - "severity": "ERROR" - }, - { - "line": 27, + "line": 26, "column": 1, - "endLine": 27, + "endLine": 26, "endColumn": 37, "problem": "UnaryArithmNotNumber", "suggest": "", diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json index 3803d40f1a..196e9489ea 100644 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.autofix.json @@ -1,18 +1,18 @@ { - "copyright": [ - "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." - ], + "copyright": [ + "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." + ], "result": [ { "line": 16, @@ -33,7 +33,7 @@ { "start": 693, "end": 693, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./no_await_js_promise_export');\nlet p = GeneratedImportVar_1.getProperty('p');\nlet foo = GeneratedImportVar_1.getProperty('foo');\nlet pFuncCall = GeneratedImportVar_1.getProperty('pFuncCall');\nlet arrowFunc = GeneratedImportVar_1.getProperty('arrowFunc');\nlet pArrowCall = GeneratedImportVar_1.getProperty('pArrowCall');\n", + "replacementText": "let p = ESValue.load('./no_await_js_promise_export').getProperty('p');\nlet foo = ESValue.load('./no_await_js_promise_export').getProperty('foo');\nlet pFuncCall = ESValue.load('./no_await_js_promise_export').getProperty('pFuncCall');\nlet arrowFunc = ESValue.load('./no_await_js_promise_export').getProperty('arrowFunc');\nlet pArrowCall = ESValue.load('./no_await_js_promise_export').getProperty('pArrowCall');\n", "line": 16, "column": 1, "endLine": 16, @@ -275,4 +275,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets index a1e4ff667c..7729b47d7a 100644 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.ets @@ -13,12 +13,11 @@ * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./no_await_js_promise_export'); -let p = GeneratedImportVar_1.getProperty('p'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let pFuncCall = GeneratedImportVar_1.getProperty('pFuncCall'); -let arrowFunc = GeneratedImportVar_1.getProperty('arrowFunc'); -let pArrowCall = GeneratedImportVar_1.getProperty('pArrowCall'); +let p = ESValue.load('./no_await_js_promise_export').getProperty('p'); +let foo = ESValue.load('./no_await_js_promise_export').getProperty('foo'); +let pFuncCall = ESValue.load('./no_await_js_promise_export').getProperty('pFuncCall'); +let arrowFunc = ESValue.load('./no_await_js_promise_export').getProperty('arrowFunc'); +let pArrowCall = ESValue.load('./no_await_js_promise_export').getProperty('pArrowCall'); async function awaitPromise() { diff --git a/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.json b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.json index 4aebfd2473..0b6e2511ce 100644 --- a/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.json +++ b/ets2panda/linter/test/interop/no_await_js_promise.ets.migrate.json @@ -18,7 +18,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 72, + "endColumn": 70, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 46, + "endColumn": 74, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 50, + "endColumn": 86, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -48,7 +48,7 @@ "line": 19, "column": 5, "endLine": 19, - "endColumn": 62, + "endColumn": 86, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,26 +58,16 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 62, + "endColumn": 88, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 21, - "column": 5, - "endLine": 21, - "endColumn": 64, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 24, + "line": 23, "column": 16, - "endLine": 24, + "endLine": 23, "endColumn": 28, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -85,9 +75,9 @@ "severity": "ERROR" }, { - "line": 28, + "line": 27, "column": 16, - "endLine": 28, + "endLine": 27, "endColumn": 33, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -95,9 +85,9 @@ "severity": "ERROR" }, { - "line": 32, + "line": 31, "column": 16, - "endLine": 32, + "endLine": 31, "endColumn": 31, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -105,9 +95,9 @@ "severity": "ERROR" }, { - "line": 36, + "line": 35, "column": 16, - "endLine": 36, + "endLine": 35, "endColumn": 30, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -115,9 +105,9 @@ "severity": "ERROR" }, { - "line": 40, + "line": 39, "column": 16, - "endLine": 40, + "endLine": 39, "endColumn": 32, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -125,9 +115,9 @@ "severity": "ERROR" }, { - "line": 45, + "line": 44, "column": 9, - "endLine": 45, + "endLine": 44, "endColumn": 20, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -135,9 +125,9 @@ "severity": "ERROR" }, { - "line": 49, + "line": 48, "column": 13, - "endLine": 51, + "endLine": 50, "endColumn": 4, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -145,9 +135,9 @@ "severity": "ERROR" }, { - "line": 54, + "line": 53, "column": 20, - "endLine": 54, + "endLine": 53, "endColumn": 21, "problem": "ObjectLiteralNoContextType", "suggest": "", @@ -155,9 +145,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 54, "column": 3, - "endLine": 57, + "endLine": 56, "endColumn": 4, "problem": "ObjectLiteralProperty", "suggest": "", @@ -165,9 +155,9 @@ "severity": "ERROR" }, { - "line": 55, + "line": 54, "column": 9, - "endLine": 55, + "endLine": 54, "endColumn": 18, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -175,9 +165,9 @@ "severity": "ERROR" }, { - "line": 59, + "line": 58, "column": 17, - "endLine": 61, + "endLine": 60, "endColumn": 4, "problem": "LimitedReturnTypeInference", "suggest": "", @@ -185,4 +175,4 @@ "severity": "ERROR" } ] -} +} \ No newline at end of file diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json index bf8dcb076d..653a902126 100644 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 692, "end": 692, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./no_js_instanceof_file.js');\nlet Foo = GeneratedImportVar_1.getProperty('Foo');\nlet foo = GeneratedImportVar_1.getProperty('foo');\nlet CreatePerson = GeneratedImportVar_1.getProperty('CreatePerson');\nlet a = GeneratedImportVar_1.getProperty('a');\nlet b = GeneratedImportVar_1.getProperty('b');\nlet MyNamespace = GeneratedImportVar_1.getProperty('MyNamespace');\n", + "replacementText": "let Foo = ESValue.load('./no_js_instanceof_file.js').getProperty('Foo');\nlet foo = ESValue.load('./no_js_instanceof_file.js').getProperty('foo');\nlet CreatePerson = ESValue.load('./no_js_instanceof_file.js').getProperty('CreatePerson');\nlet a = ESValue.load('./no_js_instanceof_file.js').getProperty('a');\nlet b = ESValue.load('./no_js_instanceof_file.js').getProperty('b');\nlet MyNamespace = ESValue.load('./no_js_instanceof_file.js').getProperty('MyNamespace');\n", "line": 16, "column": 1, "endLine": 16, diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets index 89f487d233..619b63d465 100644 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.ets @@ -13,13 +13,12 @@ * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./no_js_instanceof_file.js'); -let Foo = GeneratedImportVar_1.getProperty('Foo'); -let foo = GeneratedImportVar_1.getProperty('foo'); -let CreatePerson = GeneratedImportVar_1.getProperty('CreatePerson'); -let a = GeneratedImportVar_1.getProperty('a'); -let b = GeneratedImportVar_1.getProperty('b'); -let MyNamespace = GeneratedImportVar_1.getProperty('MyNamespace'); +let Foo = ESValue.load('./no_js_instanceof_file.js').getProperty('Foo'); +let foo = ESValue.load('./no_js_instanceof_file.js').getProperty('foo'); +let CreatePerson = ESValue.load('./no_js_instanceof_file.js').getProperty('CreatePerson'); +let a = ESValue.load('./no_js_instanceof_file.js').getProperty('a'); +let b = ESValue.load('./no_js_instanceof_file.js').getProperty('b'); +let MyNamespace = ESValue.load('./no_js_instanceof_file.js').getProperty('MyNamespace'); class Foo1 {} diff --git a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json index 4a61cb89de..7833e5b9a6 100644 --- a/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json +++ b/ets2panda/linter/test/interop/no_js_instanceof.ets.migrate.json @@ -18,7 +18,7 @@ "line": 16, "column": 5, "endLine": 16, - "endColumn": 70, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -28,7 +28,7 @@ "line": 17, "column": 5, "endLine": 17, - "endColumn": 50, + "endColumn": 72, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -38,7 +38,7 @@ "line": 18, "column": 5, "endLine": 18, - "endColumn": 50, + "endColumn": 90, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -58,7 +58,7 @@ "line": 20, "column": 5, "endLine": 20, - "endColumn": 46, + "endColumn": 68, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", @@ -68,26 +68,16 @@ "line": 21, "column": 5, "endLine": 21, - "endColumn": 46, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 22, - "column": 5, - "endLine": 22, - "endColumn": 66, + "endColumn": 88, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 71, + "line": 70, "column": 19, - "endLine": 71, + "endLine": 70, "endColumn": 24, "problem": "ClassAsObjectError", "suggest": "", @@ -95,9 +85,9 @@ "severity": "ERROR" }, { - "line": 75, + "line": 74, "column": 21, - "endLine": 75, + "endLine": 74, "endColumn": 26, "problem": "ClassAsObjectError", "suggest": "", @@ -105,9 +95,9 @@ "severity": "ERROR" }, { - "line": 79, + "line": 78, "column": 36, - "endLine": 79, + "endLine": 78, "endColumn": 59, "problem": "DynamicCtorCall", "suggest": "", diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json index b3d6f3508f..855bd5e9a2 100644 --- a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.autofix.json @@ -33,7 +33,7 @@ { "start": 654, "end": 654, - "replacementText": "let GeneratedImportVar_1 = ESValue.load('./unary_operation_js_obj_js.js');\nlet foo = GeneratedImportVar_1.getProperty('foo');\n", + "replacementText": "let foo = ESValue.load('./unary_operation_js_obj_js.js').getProperty('foo');\n", "line": 15, "column": 1, "endLine": 15, diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets index d0a648c942..2cdab6f2ed 100644 --- a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.ets @@ -12,8 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -let GeneratedImportVar_1 = ESValue.load('./unary_operation_js_obj_js.js'); -let foo = GeneratedImportVar_1.getProperty('foo'); +let foo = ESValue.load('./unary_operation_js_obj_js.js').getProperty('foo'); +foo.getProperty("num").toNumber(); diff --git a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json index 8fbd5964c4..cb1d1f02e8 100644 --- a/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json +++ b/ets2panda/linter/test/interop/unary_operation_js_obj.ets.migrate.json @@ -18,26 +18,16 @@ "line": 15, "column": 5, "endLine": 15, - "endColumn": 74, + "endColumn": 76, "problem": "AnyType", "suggest": "", "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", "severity": "ERROR" }, { - "line": 16, - "column": 5, - "endLine": 16, - "endColumn": 50, - "problem": "AnyType", - "suggest": "", - "rule": "Use explicit types instead of \"any\", \"unknown\" (arkts-no-any-unknown)", - "severity": "ERROR" - }, - { - "line": 19, + "line": 18, "column": 1, - "endLine": 19, + "endLine": 18, "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", @@ -45,9 +35,9 @@ "severity": "ERROR" }, { - "line": 20, + "line": 19, "column": 1, - "endLine": 20, + "endLine": 19, "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", @@ -55,9 +45,9 @@ "severity": "ERROR" }, { - "line": 22, + "line": 21, "column": 1, - "endLine": 22, + "endLine": 21, "endColumn": 35, "problem": "UnaryArithmNotNumber", "suggest": "", -- Gitee From e48e83d74a1f0ddb21220d0f68902feb0cb7a4ea Mon Sep 17 00:00:00 2001 From: Tatiana Titova Date: Wed, 21 May 2025 16:18:26 +0300 Subject: [PATCH 055/107] Update to Koala rev. 9 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IC9INV Signed-off-by: Tatiana Titova --- ets2panda/scripts/arkui-setup.sh | 76 ++++++++++++++++++++++++++--- ets2panda/scripts/arkui.properties | 2 +- ets2panda/scripts/hello-build.sh | 9 +--- ets2panda/scripts/shopping-build.sh | 9 +--- 4 files changed, 72 insertions(+), 24 deletions(-) mode change 100644 => 100755 ets2panda/scripts/arkui-setup.sh diff --git a/ets2panda/scripts/arkui-setup.sh b/ets2panda/scripts/arkui-setup.sh old mode 100644 new mode 100755 index 4ad11ccf3a..1a2cd0ca9d --- a/ets2panda/scripts/arkui-setup.sh +++ b/ets2panda/scripts/arkui-setup.sh @@ -13,6 +13,7 @@ # limitations under the License. set -ex +set -o pipefail function about() { cat <<-ENDHELP @@ -39,6 +40,10 @@ while [ -n "$1" ]; do about exit 0 ;; + --demo) + DEMO="${2}" + shift 2 + ;; --nexus-repo) NEXUS_REPO="${2}" shift 2 @@ -66,7 +71,7 @@ fi HUAWEI_MIRROR="${HUAWEI_MIRROR:-https://repo.huaweicloud.com/repository/npm/}" KOALA_REGISTRY="${KOALA_REGISTRY:-https://$NEXUS_REPO/repository/koala-npm/}" -NINJA_OPTIONS="-j ${NPROC_PER_JOB}" +export NINJA_OPTIONS="-j ${NPROC_PER_JOB}" retry() { local -r -i max_attempts="$1"; shift @@ -125,6 +130,7 @@ npm config set package-lock false npm config set strict-ssl false npm config set registry "${HUAWEI_MIRROR}" npm config set @koalaui:registry "${KOALA_REGISTRY}" +npm config set @idlizer:registry "${KOALA_REGISTRY}" npm config set @panda:registry "https://$NEXUS_REPO/repository/koala-npm/" npm config set @ohos:registry "https://repo.harmonyos.com/npm/" if [ -z "${KOALA_REPO}" ] ; then @@ -134,15 +140,71 @@ fi npm install -d pushd incremental/tools/panda/ || exit 1 -if [ -z "${PANDA_SDK_TARBALL}" ] ; then -npm run panda:sdk:install +if [ -z "${PANDA_SDK_HOST_TARBALL}" ] ; then + npm run panda:sdk:install else -npm install "${PANDA_SDK_TARBALL}" + npm install "${PANDA_SDK_HOST_TARBALL}" + if [ -n "${PANDA_SDK_DEV_TARBALL}" ] ; then + npm install "${PANDA_SDK_DEV_TARBALL}" + else + echo "PANDA_SDK_DEV_TARBALL is not set, skipping!" + fi fi popd >/dev/null 2>&1 || exit 1 -pushd arkoala-arkts || exit 1 -npm install -d +function run_script() { + npm run $1 | tee out.txt + if [ -n "$(grep 'Error:' out.txt)" ] ; then + exit 1 + fi +} + +export ENABLE_BUILD_CACHE=0 + +# Compile libarkts +pushd ui2abc/libarkts || exit 1 +run_script "regenerate" +run_script "compile --prefix ../fast-arktsc" +run_script "run" popd >/dev/null 2>&1 || exit 1 -return 0 +# Compile memo-plugin, ui-plugins + +# need to fix ui2abc tests +# run_script "all --prefix ui2abc" +run_script "build:all --prefix ui2abc" + +# Compile arkui implementations +run_script "build:arkui-common:inc:ui2abc --prefix arkoala-arkts/arkui-common" + +run_script "build:m3:recheck --prefix arkoala-arkts/arkui" +# rm -rf arkoala-arkts/arkui/build* +# run_script "build:m3:restart --prefix arkoala-arkts/arkui" + +# Compile UI plugin +run_script "compile --prefix ui2abc/ui-plugins" + +# Compile and executable tests for UI DSL +run_script "build:deps:m3 --prefix ets-tests" + +if [ -z "${DEMO}" ] ; then + echo "Just compiled ArkUI, but no demo specified." + exit 1 +fi + +case "${DEMO}" in + "shopping") + run_script "run:node --prefix arkoala-arkts/shopping/user" + ;; + "trivial") + run_script "run --prefix arkoala-arkts/trivial/user" + ;; + "empty") + ;; + *) + echo "Unknown demo" "${DEMO}" + exit 1 + ;; +esac + +echo "ArkUI ${DEMO} demo completed successfully." diff --git a/ets2panda/scripts/arkui.properties b/ets2panda/scripts/arkui.properties index d3237cfb8b..011d080333 100644 --- a/ets2panda/scripts/arkui.properties +++ b/ets2panda/scripts/arkui.properties @@ -1,3 +1,3 @@ ARKUI_DEV_REPO=https://gitee.com/rri_opensource/koala_projects.git -ARKUI_DEV_BRANCH=panda_rev_8-move-proxy-under-namespace +ARKUI_DEV_BRANCH=panda_rev_9 ARKUI_DEST=koala-sig diff --git a/ets2panda/scripts/hello-build.sh b/ets2panda/scripts/hello-build.sh index 1c568e8cfc..6f7e31f9a5 100755 --- a/ets2panda/scripts/hello-build.sh +++ b/ets2panda/scripts/hello-build.sh @@ -19,13 +19,6 @@ set -ex set -o pipefail SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -source "${SCRIPT_DIR}"/arkui-setup.sh - -pushd arkoala-arkts || exit 1 -NINJA_OPTIONS="${NINJA_OPTIONS}" npm run trivial:all:node:ci | tee out.txt -if [ -n "$(grep 'Error:' out.txt)" ] ; then - exit 1 -fi -popd >/dev/null 2>&1 || exit 1 +"${SCRIPT_DIR}"/arkui-setup.sh --demo trivial exit 0 diff --git a/ets2panda/scripts/shopping-build.sh b/ets2panda/scripts/shopping-build.sh index a672523db2..c539e1de7d 100755 --- a/ets2panda/scripts/shopping-build.sh +++ b/ets2panda/scripts/shopping-build.sh @@ -19,13 +19,6 @@ set -ex set -o pipefail SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")" -source "${SCRIPT_DIR}"/arkui-setup.sh - -pushd arkoala-arkts || exit 1 -NINJA_OPTIONS="${NINJA_OPTIONS}" npm run shopping:all:node | tee out.txt -if [ -n "$(grep 'Error:' out.txt)" ] ; then - exit 1 -fi -popd >/dev/null 2>&1 || exit 1 +"${SCRIPT_DIR}"/arkui-setup.sh --demo shopping exit 0 -- Gitee From 76723a083cd512f781cc4676ca8a4fb427b4b9fe Mon Sep 17 00:00:00 2001 From: Peter Pronai Date: Thu, 26 Jun 2025 13:12:13 +0000 Subject: [PATCH 056/107] Normalize YAML files and generate random ids As explained in the added REAME.md file, there were serious problems with git conflicts between PRs that add new diagnostic messages. This commit adds a script (`normalize_yaml`) that makes the contribution process a lot smoother and less error prone. Fixes #25929 internal issue. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICHUGM Signed-off-by: Peter Pronai Change-Id: Idad9ff2dbbc98a62126c27e0dc396c223ceaee7c --- .../declgen_ets2ts/declgen_ets2ts_error.yaml | 47 +- .../declgen_ets2ts_warning.yaml | 3 + .../declgen_ets2ts/isolated_declgen.yaml | 39 +- ets2panda/scripts/normalize_yaml | 170 ++ ets2panda/util/diagnostic/README.md | 19 + .../util/diagnostic/arktsconfig_error.yaml | 88 +- ets2panda/util/diagnostic/diagnostic.rb | 33 +- ets2panda/util/diagnostic/fatal.yaml | 141 +- ets2panda/util/diagnostic/semantic.yaml | 2325 +++++++++-------- ets2panda/util/diagnostic/syntax.yaml | 1948 +++++++------- ets2panda/util/diagnostic/warning.yaml | 121 +- 11 files changed, 2609 insertions(+), 2325 deletions(-) create mode 100755 ets2panda/scripts/normalize_yaml create mode 100644 ets2panda/util/diagnostic/README.md diff --git a/ets2panda/declgen_ets2ts/declgen_ets2ts_error.yaml b/ets2panda/declgen_ets2ts/declgen_ets2ts_error.yaml index 392309b9b7..71d68c0c7f 100644 --- a/ets2panda/declgen_ets2ts/declgen_ets2ts_error.yaml +++ b/ets2panda/declgen_ets2ts/declgen_ets2ts_error.yaml @@ -12,25 +12,14 @@ # limitations under the License. declgen_ets2ts_error: + - name: IDENT_KEY_SUPPORT id: 1 message: Only identifier keys are supported. -- name: UNSUPPORTED_TYPE - id: 2 - message: Unsupported type {}. - -- name: UNSUPPORTED_LITERAL_TYPE - id: 3 - message: Unsupported literal type. - -- name: UNEXPECTED_NUMBER_LITERAL_TYPE - id: 4 - message: Unexpected number literal type. - -- name: NOT_OVERLOAD_SUPPORT - id: 5 - message: Method overloads are not supported. +- name: IMPORT_SPECIFIERS_SUPPORT + id: 8 + message: Only import specifiers are supported. - name: INCORRECT_ENUM_MEMBER id: 6 @@ -40,14 +29,30 @@ declgen_ets2ts_error: id: 7 message: Only literal enum initializers are supported. -- name: IMPORT_SPECIFIERS_SUPPORT - id: 8 - message: Only import specifiers are supported. +- name: NOT_OVERLOAD_SUPPORT + id: 5 + message: Method overloads are not supported. + +- name: UNEXPECTED_NUMBER_LITERAL_TYPE + id: 4 + message: Unexpected number literal type. + +- name: UNSUPPORTED_ENCODING_SPECIFICATIONS + id: 10 + message: The source file does not comply with the encoding specifications. For details, please see the following error + information. + +- name: UNSUPPORTED_LITERAL_TYPE + id: 3 + message: Unsupported literal type. - name: UNSUPPORTED_LOCAL_BINDINGS id: 9 message: Imports with local bindings are not supported. -- name: UNSUPPORTED_ENCODING_SPECIFICATIONS - id: 10 - message: The source file does not comply with the encoding specifications. For details, please see the following error information. +- name: UNSUPPORTED_TYPE + id: 2 + message: Unsupported type {}. + +graveyard: [] +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/declgen_ets2ts/declgen_ets2ts_warning.yaml b/ets2panda/declgen_ets2ts/declgen_ets2ts_warning.yaml index 610c7d89a1..48ad687679 100644 --- a/ets2panda/declgen_ets2ts/declgen_ets2ts_warning.yaml +++ b/ets2panda/declgen_ets2ts/declgen_ets2ts_warning.yaml @@ -12,6 +12,7 @@ # limitations under the License. declgen_ets2ts_warning: + - name: EMPTY_TYPE_NAME id: 1 message: Object type name is empty. @@ -19,3 +20,5 @@ declgen_ets2ts_warning: - name: UNTYPED_METHOD id: 2 message: Untyped method encountered {}. +graveyard: [] +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/declgen_ets2ts/isolated_declgen.yaml b/ets2panda/declgen_ets2ts/isolated_declgen.yaml index bfde0c6897..af8bb6fe7f 100644 --- a/ets2panda/declgen_ets2ts/isolated_declgen.yaml +++ b/ets2panda/declgen_ets2ts/isolated_declgen.yaml @@ -11,25 +11,11 @@ # See the License for the specific language governing permissions and # limitations under the License. isolated_declgen: -- name: VARABLE_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL - id: 1 - message: Variable must have an explicit type annotation when using isolated declaration. - -- name: PARAMETER_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL - id: 2 - message: Parameter must have an explicit type annotation when using isolated declaration. - -- name: PROPERTY_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL - id: 3 - message: Property must have an explicit type annotation when using isolated declaration. - -- name: ONLY_CONST_ARRAYS_CAN_BE_INFERRED_WITH_ISOLATED_DECL - id: 4 - message: Only const arrays can be inferred with isolated declaration. - name: DECLARATION_EMIT_FOR_THIS_PARAMETER_REQUIRES_IMPLICITLY_ADD_UNDEFINED_TO_ITS_TYPE_NOT_ALLOWED_IN_ISOLATED_DECL id: 5 - message: Declaration emit for this parameter requires implicitly adding undefined to its type, which is not allowed in isolated declaration. + message: Declaration emit for this parameter requires implicitly adding undefined to its type, which is not allowed in + isolated declaration. - name: DEFAULT_EXPORTS_CANNOT_BE_INFERRED_WITH_ISOLATED_DECL id: 6 @@ -41,4 +27,23 @@ isolated_declgen: - name: METHOD_MUST_HAVE_AN_EXPLICIT_RETURN_TYPE_ANNOTATION_WITH_ISOLATED_DECL id: 8 - message: Method must have an explicit return type annotation when using isolated declaration. \ No newline at end of file + message: Method must have an explicit return type annotation when using isolated declaration. + +- name: ONLY_CONST_ARRAYS_CAN_BE_INFERRED_WITH_ISOLATED_DECL + id: 4 + message: Only const arrays can be inferred with isolated declaration. + +- name: PARAMETER_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL + id: 2 + message: Parameter must have an explicit type annotation when using isolated declaration. + +- name: PROPERTY_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL + id: 3 + message: Property must have an explicit type annotation when using isolated declaration. + +- name: VARABLE_MUST_HAVE_EXPLICIT_TYPE_ANNOTATION_WITH_ISOLATED_DECL + id: 1 + message: Variable must have an explicit type annotation when using isolated declaration. + +graveyard: [] +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/scripts/normalize_yaml b/ets2panda/scripts/normalize_yaml new file mode 100755 index 0000000000..71ff8527fc --- /dev/null +++ b/ets2panda/scripts/normalize_yaml @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# 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. + +# NOTE(pronai) need idempotence test and negative tests for non-normal YAMLs + +import io +import os +import posixpath +import shutil +import subprocess +import sys +# YAML parser/dumper that preserves formatting +from ruamel import yaml +import numpy as np +import math + +usage = f"""\ +Usage: {sys.argv[0]} [--all] inputs + + inputs: a (possibly empty) list of paths to diagnostic YAMLs + --all: run on all YAMLs that look like they include diagnostics + -h | --help: print this help + """ + +permissible_collision_chance = 0.001 +simultaneous_commits = 10 +# how many new ids each commit adds, based on analysis of previous commits, this is ceil(avg) +# it must be a positive int +ids_per_commit = 2 +# we model commits with multiple ids as two commits +# this makes the math a lot easier and is a pessimistic approximation +effective_alloc_rate = simultaneous_commits * ids_per_commit + + +# see https://en.wikipedia.org/wiki/Birthday_problem +def collision_prob(n): + # the factorials are optimized away + return 1 - math.prod(range(n - effective_alloc_rate + 1, n+1)) / n ** effective_alloc_rate + +# binary search for a solution +def compute_range(): + min_range = effective_alloc_rate + upper_bound = min_range + lower_bound = min_range + step = 1 + while collision_prob(upper_bound) >= permissible_collision_chance: + lower_bound = upper_bound + upper_bound+=step + step*=2 + while lower_bound < upper_bound: + mid = (upper_bound+lower_bound)/2 + # n must be integer + mid_lo = math.floor(mid) + mid_hi = math.ceil(mid) + p_lo = collision_prob(mid_lo) + p_hi = collision_prob(mid_hi) + # higher n gives lower p! + if p_hi > permissible_collision_chance: + # p is too high, need higher n + lower_bound = mid_hi + else: # p_hi <= permissible_collision_chance + if permissible_collision_chance > p_lo: + upper_bound = mid_lo + else: # permissible_collision_chance <= p_lo + min_range = mid_hi + break + return min_range + +min_range = compute_range() + +# needed to make sure we are using the right numpy dtype +assert math.ceil(math.log2(min_range))<32 +dtype = np.uint32 + +def normalize(in_path): + out_path = in_path + ".new" + with open(in_path) as in_file, open(out_path, "w+") as out_file: + parser = yaml.YAML() + parser.preserve_quotes = True + parser.width = 120 + docs = parser.load(in_file) + doc = docs[next(iter(docs.keys()))] + doc.sort(key=lambda item: item['name']) + rng = np.random.default_rng() + if "graveyard" in docs: + docs["graveyard"].sort() + for diagnostic in doc: + if "id" in diagnostic and "graveyard" in docs: + continue + # we re-compute this every time because it's easier than splitting the ranges after each allocation + # it can be optimized later if necessary + # either way, we only add 1-2 IDs in each commit, so at most it doubles the run time + allocated = np.fromiter((int(diagnostic['id']) for diagnostic in doc if 'id' in diagnostic), dtype) + # add 0 as sentinel value, so we can deal with deletions + # 1 is the first actually available id, it's taken as of press time, but it might not remain that way + allocated = np.append(allocated, [0]) + allocated.sort() + if "graveyard" not in docs: + print(f"{in_path}: filling graveyard") + docs.insert(len(docs), "graveyard", sorted(list(set(range(1, allocated[-1]+1)).difference(set(allocated))))) + if 'id' in diagnostic: + continue + allocated = np.append(allocated, docs["graveyard"]) + allocated.sort() + gaps = allocated[1:]-allocated[:-1]-1 + gaps = np.append(gaps, [min_range-gaps.sum()]) + non_unique = gaps<0 + assert len(gaps) == len(allocated) + if np.any(non_unique): + raise ValueError(f"Non unique ids in yaml {in_path}:", allocated[non_unique]) + # choose from the available intervals using their size as weight + p = gaps + # need to normalize them so they sum to 1 + p = p / np.sum(p, dtype=float) + ival_id = rng.choice(len(allocated), p=p) + ival_start = 1+allocated[ival_id] + ival_size = gaps[ival_id] + # generate a random number from the interval + iid = ival_start+rng.choice(ival_size) + gaps[ival_id]-=1 + diagnostic.insert(1, 'id', int(iid)) + sio = io.StringIO() + parser.dump(docs, sio) + contents = sio.getvalue() + # make sure there is at least one blank line before each list item + prev="not blank" + for line in contents.splitlines(keepends=True): + # print("prev", prev) + # print("line", line) + if line.lstrip().startswith("- name:") and prev.strip()!="": + out_file.write("\n") + pass + out_file.write(line) + prev=line + usage_comment = "# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing.\n" + if prev.strip() != usage_comment.strip(): + out_file.write(usage_comment) + os.rename(out_path, in_path) + +def known_file_paths(): + repo_base = posixpath.dirname(shutil.which(sys.argv[0])) + "/../../" + for relative in subprocess.run(["git", "grep", "--files-with-matches", "-e" "^ message:", "--", "**.yaml"], cwd = repo_base, stdout=subprocess.PIPE).stdout.decode().splitlines(): + yield repo_base + relative + +def main(): + params = sys.argv[1:] + if "-h" in sys.argv or "--help" in params: + print(usage, file=sys.stderr) + sys.exit(1) + if "--all" in params: + params = [p for p in params if p != "--all"] + for path in known_file_paths(): + params.append(path) + for path in params: + print("Processing", path) + normalize(path) + +if __name__ == "__main__": + main() diff --git a/ets2panda/util/diagnostic/README.md b/ets2panda/util/diagnostic/README.md new file mode 100644 index 0000000000..042c927578 --- /dev/null +++ b/ets2panda/util/diagnostic/README.md @@ -0,0 +1,19 @@ +# Diagnostic YAMLs +These files encode the various diagnostic messages that es2panda might emit. + +## Adding new diagnostics +When adding a new diagnostic, adding them at the end *guarantees* conflicts between PRs. We avoid that by keeping the lists sorted by name. + +Keeping them sorted still doesn't solve the issue of two PRs trying to add diagnostics with the same id. We mostly solve that by *not* choosing the numbers by hand, nor just incrementing them, but by generating them randomly. + +Both are achieved by running `ets_frontend/ets2panda/scripts/normalize_yaml somefile.yaml`, where `somefile.yaml` is the one you have added new messages to. + +You can also run `normalize_yaml --all` to normalize all diagnostic YAMLs. + +## Deleting diagnostics +To avoid accidentally re-using old ids, please move them into the `graveyard` list at the end of the file. These are forever forbidden from being emitted by the compiler. + +See `semantic.yaml` for an example of how it should look. + +## Checking +YAMLs are checked at build time in `ets_frontend/ets2panda/util/diagnostic/diagnostic.rb`. \ No newline at end of file diff --git a/ets2panda/util/diagnostic/arktsconfig_error.yaml b/ets2panda/util/diagnostic/arktsconfig_error.yaml index e03085e195..d839babae0 100644 --- a/ets2panda/util/diagnostic/arktsconfig_error.yaml +++ b/ets2panda/util/diagnostic/arktsconfig_error.yaml @@ -12,45 +12,22 @@ # limitations under the License. arkts_config_error: -- name: UNRESOLVABLE_CONFIG_PATH - id: 1 - message: Can't resolve config path {} - name: CYCLIC_IMPORT id: 2 message: Encountered cyclic import in 'extends' field -- name: WRONG_BASE_CONFIG - id: 3 - message: Failed to parse base config {} - -- name: INVALID_VALUE - id: 4 - message: Invalid value for '{}' with key '{}' - -- name: EMPTY_ARRAY_SUBSTITOTIONS - id: 5 - message: Substitutions for pattern '{}' shouldn't be an empty array - -- name: INVALID_LANGUAGE - id: 6 - message: Invalid '{}' value for dynamic path with key '{}'. Should be one of {} - -- name: UNSUPPORTED_LANGUAGE_FOR_INTEROP - id: 7 - message: Interoperability with language '{}' is not supported - -- name: INVALID_NAMED_VALUE - id: 8 - message: Invalid {} value for '{}' with key '{}' +- name: DEPENDENCIES_ABSOLUTE + id: 18 + message: "Don't use absolute path '{}' as key in 'dependencies'" - name: DUPLICATED_DEPENDENCIES id: 9 message: Duplicated dynamic path '{}' for key '{}' -- name: INVALID_JSON_TYPE - id: 10 - message: The '{}' must have {} type +- name: EMPTY_ARRAY_SUBSTITOTIONS + id: 5 + message: Substitutions for pattern '{}' shouldn't be an empty array - name: EMPTY_LIST id: 11 @@ -60,26 +37,53 @@ arkts_config_error: id: 12 message: Failed to open file {} +- name: INVALID_DESTINATION_FILE + id: 16 + message: Invalid destination file + - name: INVALID_JSON id: 13 message: ArkTsConfig is not valid json -- name: NO_FILE - id: 14 - message: No such file {} +- name: INVALID_JSON_TYPE + id: 10 + message: The '{}' must have {} type -- name: NOT_ROOT_DIR - id: 15 - message: '{} is not root directory for {}' - -- name: INVALID_DESTINATION_FILE - id: 16 - message: Invalid destination file +- name: INVALID_LANGUAGE + id: 6 + message: Invalid '{}' value for dynamic path with key '{}'. Should be one of {} + +- name: INVALID_NAMED_VALUE + id: 8 + message: Invalid {} value for '{}' with key '{}' - name: INVALID_PATH id: 17 message: Invalid path for '{}' in dependencies -- name: DEPENDENCIES_ABSOLUTE - id: 18 - message: "Don't use absolute path '{}' as key in 'dependencies'" \ No newline at end of file +- name: INVALID_VALUE + id: 4 + message: Invalid value for '{}' with key '{}' + +- name: NOT_ROOT_DIR + id: 15 + message: '{} is not root directory for {}' + +- name: NO_FILE + id: 14 + message: No such file {} + +- name: UNRESOLVABLE_CONFIG_PATH + id: 1 + message: Can't resolve config path {} + +- name: UNSUPPORTED_LANGUAGE_FOR_INTEROP + id: 7 + message: Interoperability with language '{}' is not supported + +- name: WRONG_BASE_CONFIG + id: 3 + message: Failed to parse base config {} + +graveyard: [] +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/util/diagnostic/diagnostic.rb b/ets2panda/util/diagnostic/diagnostic.rb index 0e83ecce9e..d770ba5b0e 100644 --- a/ets2panda/util/diagnostic/diagnostic.rb +++ b/ets2panda/util/diagnostic/diagnostic.rb @@ -25,9 +25,40 @@ module Diagnostic @diagnostics end + def normalization_error + warn "You probably need to run 'normalize_yaml', see ets_frontend/ets2panda/util/diagnostic/README.md" + Kernel.exit 1 + end + def wrap_data(data) + graveyard = data.delete_field(:graveyard) + data.freeze + graveyard.each_cons(2) do |lhs, rhs| + if lhs >= rhs + warn "Graveyard is not strictly monotonically sorted, '#{lhs}' should come before '#{rhs}'" + normalization_error + end + end + graveyard = graveyard.to_set data.each_pair do |diagnostic_type, diagnostics| - diagnostics.each.with_index(1) do |diagnostic, index| + # Check if the YAML is in normal form according to ets_frontend/ets2panda/util/diagnostic/normalize_yaml + diagnostics.map(&:name).each_cons(2) do |lhs, rhs| + if lhs >= rhs + warn "Message with name '#{lhs}' should come after '#{rhs}' for diagnostic type '#{diagnostic_type}'" + normalization_error + end + end + diagnostics.map(&:id).each do |id| + if graveyard.member? id + warn "'#{id}' used for diagnostic type #{diagnostic_type} is already in the graveyard, let it rest in peace" + normalization_error + end + end + diagnostics.map(&:id).group_by(&:itself).select{ |_, v| v.size > 1 }.map(&:first).each do |duplicate| + warn "Duplicate id '#{duplicate}' for diagnostic type '#{diagnostic_type}'" + normalization_error + end + diagnostics.each do |diagnostic| diagnostic.type = diagnostic_type @diagnostics.append(diagnostic) end diff --git a/ets2panda/util/diagnostic/fatal.yaml b/ets2panda/util/diagnostic/fatal.yaml index 5cd4141733..be12c9338f 100644 --- a/ets2panda/util/diagnostic/fatal.yaml +++ b/ets2panda/util/diagnostic/fatal.yaml @@ -12,106 +12,111 @@ # limitations under the License. fatal: -- name: TBD1 - id: 1 - message: . -- name: OPEN_FAILED - id: 2 - message: "Failed to open file: {}" +- name: ASSIGN_PROFILE_INFO_FAILED + id: 23 + message: "AssignProfileInfo failed" -- name: NO_INPUT - id: 3 - message: "No files to compile" +- name: COMPILE_FAILED + id: 21 + message: "Failed to compile from {} to {}" -- name: PLUGIN_LOAD_FAILED - id: 4 - message: "Failed to load plugin {}" +- name: DUMP_ETS_INVALID_EXT + id: 8 + message: "--dump-ets-src-* option is valid only with ETS extension" + +- name: EMIT_FAILED + id: 22 + message: "Failed to emit binary data: {}" + +- name: EMPTY_IMPORT_PATH + id: 15 + message: "Import path cannot be empty" - name: EVAL_MODE_NOT_SINGLE_INPUT id: 5 message: "When compiling with --debugger-eval-mode single input file must be provided" -- name: PROJ_COMP_WITH_OUTPUT - id: 6 - message: "When compiling in project mode --output key is not needed" - -- name: MODULE_INVALID_EXT - id: 7 - message: "--module is not supported for this extension." - -- name: DUMP_ETS_INVALID_EXT - id: 8 - message: "--dump-ets-src-* option is valid only with ETS extension" +- name: GENERATE_DYNAMIC_DECLARATIONS + id: 24 + message: "Genate dynamic declarations, outputDeclEts and outputEts must be set together." -- name: PROJECT_EXT_NOT_ETS - id: 9 - message: "Error: only '--extension=ets' is supported for project compilation mode." +- name: IMPORT_CANT_FIND_PREFIX + id: 16 + message: "Can't find prefix for '{}' in {}" -- name: UNKNOWN_EXT - id: 10 - message: "Unknown extension of sourcefile, set the '--extension' option or change the file extension (available options: js, ts, as, ets)" +- name: INVALID_ARKTSCONFIG + id: 13 + message: "Invalid ArkTsConfig: {}" - name: JS_UNSUPPORTED id: 11 message: "js extension is not supported within current build" -- name: OPEN_FAILED_ARKTSCONF - id: 12 - message: "Failed to open arktsconfig: {}" +- name: MISSING_OUTPUT_FILE + id: 25 + message: "Output file path must be specified." -- name: INVALID_ARKTSCONFIG - id: 13 - message: "Invalid ArkTsConfig: {}" +- name: MODULE_INVALID_EXT + id: 7 + message: "--module is not supported for this extension." -- name: UNRESOLVED_MODULE - id: 14 - message: "Unresolved module name {}" +- name: NO_INPUT + id: 3 + message: "No files to compile" -- name: EMPTY_IMPORT_PATH - id: 15 - message: "Import path cannot be empty" +- name: OPEN_FAILED + id: 2 + message: "Failed to open file: {}" -- name: IMPORT_CANT_FIND_PREFIX - id: 16 - message: "Can't find prefix for '{}' in {}" +- name: OPEN_FAILED_ARKTSCONF + id: 12 + message: "Failed to open arktsconfig: {}" - name: OPEN_FOLDER_FAILED id: 17 message: "Cannot open folder: {}" -- name: UNAVAILABLE_SRC_PATH - id: 18 - message: "Not an available source path: {}" +- name: PLUGIN_LOAD_FAILED + id: 4 + message: "Failed to load plugin {}" -- name: UNSUPPORTED_PATH - id: 19 - message: "Not supported path: {}" +- name: PROJECT_EXT_NOT_ETS + id: 9 + message: "Error: only '--extension=ets' is supported for project compilation mode." + +- name: PROJ_COMP_WITH_OUTPUT + id: 6 + message: "When compiling in project mode --output key is not needed" + +- name: SIMULTANEOUSLY_MARK_FAILED + id: 26 + message: "simultaneously compile is not work because of input file paths error." - name: SOURCE_OUTSIDE_ETS_PATH id: 20 message: "Source file {} outside ets-path" -- name: COMPILE_FAILED - id: 21 - message: "Failed to compile from {} to {}" +- name: TBD1 + id: 1 + message: . -- name: EMIT_FAILED - id: 22 - message: "Failed to emit binary data: {}" +- name: UNAVAILABLE_SRC_PATH + id: 18 + message: "Not an available source path: {}" -- name: ASSIGN_PROFILE_INFO_FAILED - id: 23 - message: "AssignProfileInfo failed" +- name: UNKNOWN_EXT + id: 10 + message: "Unknown extension of sourcefile, set the '--extension' option or change the file extension (available options: + js, ts, as, ets)" -- name: GENERATE_DYNAMIC_DECLARATIONS - id: 24 - message: "Genate dynamic declarations, outputDeclEts and outputEts must be set together." +- name: UNRESOLVED_MODULE + id: 14 + message: "Unresolved module name {}" -- name: MISSING_OUTPUT_FILE - id: 25 - message: "Output file path must be specified." +- name: UNSUPPORTED_PATH + id: 19 + message: "Not supported path: {}" -- name: SIMULTANEOUSLY_MARK_FAILED - id: 26 - message: "simultaneously compile is not work because of input file paths error." +graveyard: [] +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 8de38bb1ef..0def07ffc8 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -12,158 +12,118 @@ # limitations under the License. semantic: -- name: ASYNC_FUNCTION_RETURN_TYPE - id: 1 - message: Return type of async function must be 'Promise'. - -- name: NO_CALL_SIGNATURE - id: 2 - message: Type '{}' has no call signatures. - -- name: INVALID_ANNOTATION_RETENTION - id: 3 - message: Annotation '@Retention' can only be applied to annotation declarations. - -- name: ANNOTATION_POLICY_INVALID - id: 4 - message: Invalid value for 'policy' field. The policy must be one of the following:'SOURCE', 'CLASS', or 'RUNTIME'. - -- name: ANNOTATION_ON_LAMBDA_LOCAL_TYPE - id: 5 - message: Annotations without 'SOURCE' cannot be used on lambda expressions, local declarations, or types. - -- name: STANDARD_ANNOTATION_REQUIRED - id: 6 - message: Only standard annotations are allowed to be applied on annotations. - -- name: TYPE_PARAMETER_AS_ARRAY_ELEMENT_TYPE - id: 7 - message: Cannot use array creation expression with type parameter. - -- name: VOID_IN_LOGIC - id: 9 - message: "An expression of type 'void' cannot be tested for truthiness" - -- name: POSSIBLY_NULLISH - id: 10 - message: "Value is possibly nullish." - -- name: ILLEGAL_UNARY_OP - id: 11 - message: "Illegal unary operator." -- name: ANNOTATION_FIELD_NONLITERAL - id: 12 - message: "Invalid value for annotation field, expected a constant literal." +- name: ABSTRACT_CALL + id: 26 + message: "Cannot call abstract method!" -- name: EXCEPTION_REDECLARATION - id: 13 - message: "Redeclaration of exception type" +- name: ABSTRACT_CLASS_AS_ARRAY_ELEMENT_TYPE + id: 50 + message: "Cannot use array creation expression with abstract classes and interfaces." -- name: STATIC_INIT_IN_NESTED_CLASS - id: 14 - message: "Static initializer is not allowed in inner class." +- name: ABSTRACT_INSTANTIATION + id: 52 + message: "{} is abstract therefore cannot be instantiated." -- name: NATIVE_WITHOUT_RETURN - id: 15 - message: "'Native' method should have explicit return type" +- name: ABSTRACT_IN_CONCRETE + id: 19 + message: "Non abstract class has abstract method." -- name: FUNC_EXPR_INVALID - id: 16 - message: "Invalid function expression" +- name: ABSTRACT_IS_FINAL + id: 186 + message: "Cannot use both 'final' and 'abstract' modifiers." -- name: FUNCTION_WITHOUT_BODY - id: 17 - message: "Only abstract or native methods can't have body." +- name: ABSTRACT_METHOD_INVALID_MODIFIER + id: 47 + message: "Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier." -- name: MISSING_RETURN_TYPE - id: 18 - message: "Native and Declare methods should have explicit return type." +- name: ABSTRACT_METH_IN_ABSTRACT_CLASS + id: 257 + message: "Abstract class has abstract method {}" -- name: ABSTRACT_IN_CONCRETE - id: 19 - message: "Non abstract class has abstract method." +- name: ACCESSORS_MOD_MISMATCH + id: 220 + message: "Getter and setter methods must have the same accessor modifiers" -- name: UNSUPPORTED_CLASS_LITERAL - id: 20 - message: "Class literal is not yet supported." +- name: AMBIENT_ANNOT_FIELD_INIT_MISMATCH + id: 36 + message: "The initial value does not match the expected value." -- name: INVALID_DOT_CLASS - id: 21 - message: "Invalid .class reference" +- name: AMBIENT_ANNOT_FIELD_MISMATCH + id: 39 + message: "Initializer for field '{}' does not match the expected definition in the ambient annotation '{}'." -- name: ARRAY_OF_NEVER - id: 22 - message: "Cannot use array creation expression with never type." +- name: AMBIENT_ANNOT_FIELD_MISSING_IMPL + id: 40 + message: "Field '{}' in annotation '{}' is declared in the ambient declaration but missing in the implementation." -- name: ASYNC_DOESNT_PROMISE - id: 23 - message: "Return type of async lambda must be 'Promise'" +- name: AMBIENT_ANNOT_FIELD_TYPE_MISMATCH + id: 38 + message: "Field '{}' has a type mismatch with the ambient annotation '{}'." -- name: ARRAY_LENGTH_MODIFICATION - id: 24 - message: "Setting the length of an array is not permitted" +- name: AMBIENT_ANNOT_IMPL_OF_UNDEFINED_FIELD + id: 37 + message: "Field '{}' is not defined in the ambient annotation '{}'" -- name: ASSIGNMENT_INVALID_LHS - id: 25 - message: "Invalid left-hand side of assignment expression" - code_fix_ids: [FixConvertConstToLet] +- name: AMBIENT_CONST_INVALID_LIT + id: 175 + message: "A 'const' initializer in an ambient context must be a string or numeric literal: {}" -- name: ABSTRACT_CALL - id: 26 - message: "Cannot call abstract method!" +- name: AMBIGUOUS_CALL + id: 142 + message: "Call to `{}` is ambiguous as `2` versions of `{}` are available: `{}{}` and `{}{}`" -- name: READONLY_CALL - id: 27 - message: "Cannot call readonly type methods." +- name: AMBIGUOUS_CALL_2 + id: 129 + message: "Call to `{}` is ambiguous " -- name: TEMPLATE_COUNT_MISMATCH - id: 28 - message: "Invalid string template expression" +- name: AMBIGUOUS_EXPORT + id: 362 + message: "Ambiguous export '{}'" -- name: ASSERT_MESSAGE_NOT_STRING - id: 30 - message: "Assert message must be string" +- name: AMBIGUOUS_FUNC_INIT + id: 154 + message: "Ambiguous function initialization because of multiple overloads" -- name: RETURN_THIS_OUTSIDE_METHOD - id: 31 - message: "Only extension function or a class method can return 'this'" +- name: AMBIGUOUS_FUNC_REF + id: 126 + message: "Reference to {} is ambiguous" -- name: RETURN_WITHOUT_VALUE - id: 32 - message: "Missing return value." +- name: AMBIGUOUS_REFERENCE + id: 61 + message: "Ambiguous reference to '{}'" -- name: NON_VOID_RETURN_IN_CONSTRUCTOR - id: 33 - message: "Return statement with expression isn't allowed in constructor." +- name: AMBIGUOUS_UNION_TYPE_OP + id: 255 + message: "Ambiguous union type operation" -- name: CATCH_DEFAULT_NOT_LAST - id: 34 - message: "Default catch clause should be the last in the try statement" +- name: ANALYSIS_ERRORS + id: 119 + message: "There were errors during assign analysis ({})" -- name: ENUM_TYPE_INVALID - id: 35 - message: "Invalid enumeration value type." +- name: ANNOTATION_ARG_COUNT_MISMATCH + id: 68 + message: "The number of arguments provided for the annotation exceeds the number of fields defined." -- name: AMBIENT_ANNOT_FIELD_INIT_MISMATCH - id: 36 - message: "The initial value does not match the expected value." +- name: ANNOTATION_AS_TYPE + id: 159 + message: "Annotations cannot be used as a type." -- name: AMBIENT_ANNOT_IMPL_OF_UNDEFINED_FIELD - id: 37 - message: "Field '{}' is not defined in the ambient annotation '{}'" +- name: ANNOTATION_FIELD_NONLITERAL + id: 12 + message: "Invalid value for annotation field, expected a constant literal." -- name: AMBIENT_ANNOT_FIELD_TYPE_MISMATCH - id: 38 - message: "Field '{}' has a type mismatch with the ambient annotation '{}'." +- name: ANNOTATION_ON_LAMBDA_LOCAL_TYPE + id: 5 + message: Annotations without 'SOURCE' cannot be used on lambda expressions, local declarations, or types. -- name: AMBIENT_ANNOT_FIELD_MISMATCH - id: 39 - message: "Initializer for field '{}' does not match the expected definition in the ambient annotation '{}'." +- name: ANNOTATION_POLICY_INVALID + id: 4 + message: Invalid value for 'policy' field. The policy must be one of the following:'SOURCE', 'CLASS', or 'RUNTIME'. -- name: AMBIENT_ANNOT_FIELD_MISSING_IMPL - id: 40 - message: "Field '{}' in annotation '{}' is declared in the ambient declaration but missing in the implementation." +- name: ANNOTATION_UNUSED_GENERIC_ALIAS + id: 71 + message: "Type alias generic parameter '{}' is not used in type annotation" - name: ANNOT_DUPLICATE id: 41 @@ -171,603 +131,741 @@ semantic: - name: ANNOT_FIELD_INVALID_TYPE id: 42 - message: "Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for annotation fields." - -- name: ANNOT_MULTIPLE_FIELD - id: 43 - message: "Annotation '{}' requires multiple fields to be specified." + message: "Invalid annotation field type. Only numeric, boolean, string, enum, or arrays of these types are permitted for + annotation fields." - name: ANNOT_FIELD_NO_VAL id: 44 message: "The required field '{}' must be specified. Fields without default values cannot be omitted." +- name: ANNOT_IS_VOID + id: 232 + message: "'void' used as type annotation." + +- name: ANNOT_MULTIPLE_FIELD + id: 43 + message: "Annotation '{}' requires multiple fields to be specified." + - name: ANNOT_PROP_UNDEFINED id: 45 message: "The parameter '{}' does not match any declared property in the annotation '{}'." -- name: TYPE_MISMATCH_AT_IDX - id: 46 - message: "Type '{}' is not compatible with type '{}' at index {}" +- name: ANNOT_WITHOUT_AT + id: 230 + message: "Annotation missing '@' symbol before annotation name." -- name: ABSTRACT_METHOD_INVALID_MODIFIER - id: 47 - message: "Invalid method modifier(s): an abstract method can't have private, override, static, final or native modifier." +- name: ARG_IS_CLASS_ID + id: 122 + message: "Class name can't be the argument of function or method." -- name: FINAL_METHOD_INVALID_MODIFIER - id: 48 - message: "Invalid method modifier(s): a final method can't have abstract or static modifier." +- name: ARRAY_ELEMENT_INIT_TYPE_INCOMPAT + id: 227 + message: "Array element at index {} with type '{}' is not compatible with the target array element type '{}'" -- name: SPREAD_OF_INVALID_TYPE - id: 49 - message: "Spread expression can be applied only to array or tuple type, but '{}' is provided" +- name: ARRAY_ELEMENT_UNASSIGNABLE + id: 54 + message: "Array element type '{}' is not assignable to explicit type '{}'" -- name: ABSTRACT_CLASS_AS_ARRAY_ELEMENT_TYPE - id: 50 - message: "Cannot use array creation expression with abstract classes and interfaces." +- name: ARRAY_LENGTH_MODIFICATION + id: 24 + message: "Setting the length of an array is not permitted" -- name: NON_SUPERTYPE_OF_UNDEFINED_AS_ARRAY_ELEMENT_TYPE - id: 51 - message: "Cannot use array creation expression with non-constructable element type which is non-assignable from undefined." +- name: ARRAY_OF_NEVER + id: 22 + message: "Cannot use array creation expression with never type." -- name: ABSTRACT_INSTANTIATION - id: 52 - message: "{} is abstract therefore cannot be instantiated." +- name: ARROW_TYPE_MISMATCH + id: 91 + message: "Type '{}' is not compatible with the enclosing method's return type '{}'" -- name: NONLITERAL_INSTANTIATION - id: 53 - message: "Required type can be instantiated only with object literal" +- name: ASSERT_MESSAGE_NOT_STRING + id: 30 + message: "Assert message must be string" -- name: ARRAY_ELEMENT_UNASSIGNABLE - id: 54 - message: "Array element type '{}' is not assignable to explicit type '{}'" +- name: ASSIGNMENT_INVALID_LHS + id: 25 + message: "Invalid left-hand side of assignment expression" + code_fix_ids: [FixConvertConstToLet] -- name: INVALID_SPREAD_IN_TUPLE - id: 55 - message: "'{}' cannot be spread in tuple." +- name: ASSIGN_TO_READONLY_PROP + id: 209 + message: "Cannot assign to this property because it is readonly." -- name: TUPLE_SIZE_MISMATCH - id: 56 - message: "Too many elements in array initializer for tuple with size of {}" +- name: ASYNC_DOESNT_PROMISE + id: 23 + message: "Return type of async lambda must be 'Promise'" -- name: TUPLE_UNASSIGNABLE_ARRAY - id: 57 - message: "Array initializer's type is not assignable to tuple type at index: {}" +- name: ASYNC_FUNCTION_RETURN_TYPE + id: 1 + message: Return type of async function must be 'Promise'. -- name: READONLY_ARRAYLIKE_MODIFICATION - id: 58 - message: "Cannot modify an array or tuple content that has the readonly parameter" +- name: AWAITED_NOT_PROMISE + id: 303 + message: "'await' expressions require Promise object as argument." -- name: EXTENSION_ACCESSOR_INVALID_CALL - id: 59 - message: "Extension accessor can't be used as a method call or function call." +- name: BINOP_DYN_UNIMPLEMENTED + id: 112 + message: "Unimplemented case in dynamic type comparison." -- name: UNCALLABLE_TYPE - id: 60 - message: "Type '{}' has no call signatures." +- name: BINOP_INCOMPARABLE + id: 114 + message: "Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type." -- name: AMBIGUOUS_REFERENCE - id: 61 - message: "Ambiguous reference to '{}'" +- name: BINOP_INVALID_TYPE + id: 105 + message: "Operator '{}' cannot be applied to types '{}' and '{}'." -- name: CLASS_COMPOSITE_UNKNOWN_TYPE - id: 62 - message: "need to specify target type for class composite" +- name: BINOP_MISMATCHED_ENUMS + id: 113 + message: "Bad operand type, the types of the operands must be the same enum type." -- name: CLASS_COMPOSITE_INVALID_TARGET - id: 63 - message: "Target type for class composite needs to be an object type, found '{}'" +- name: BINOP_NONARITHMETIC_TYPE + id: 108 + message: "Bad operand type, the types of the operands must be numeric type, enum or String." -- name: OBJECT_LITERAL_NOT_KV - id: 64 - message: "The object literal properties must be key-value pairs" +- name: BINOP_NOT_LOGICAL + id: 110 + message: "Bad operand type, the types of the operands must be of possible condition type." -- name: UNDEFINED_PROPERTY - id: 65 - message: "type {} has no property named {}" +- name: BINOP_NOT_REFERENCE + id: 111 + message: "Both operands have to be reference types" -- name: OPERAND_NOT_NUMERIC - id: 66 - message: "Bad operand type, the type of the operand must be numeric type." +- name: BINOP_NOT_SAME + id: 115 + message: "Bad operand type, the types of the operands must be same type." -- name: NOT_AN_ANNOTATION - id: 67 - message: "'{}' is not an annotation." +- name: BINOP_ON_UNION + id: 106 + message: "Bad operand type: multiple types left in the normalized union type ({}). Unions are not allowed in binary expressions + except equality." -- name: ANNOTATION_ARG_COUNT_MISMATCH - id: 68 - message: "The number of arguments provided for the annotation exceeds the number of fields defined." +- name: BINOP_UNEXPECTED_ERROR + id: 118 + message: "Unexpected type error in binary expression" -- name: ITERATOR_ELEMENT_TYPE_MISMATCH - id: 69 - message: "Source element type '{}' is not assignable to the loop iterator type '{}'." +- name: BINOP_UNION + id: 109 + message: "Bad operand type, unions are not allowed in binary expressions except equality." -- name: NONEXISTENT_TYPE - id: 70 - message: "'{}' type does not exist." +- name: CALLEE_NONCONSTRUCTIBLE + id: 290 + message: "Type '{}' is not constructible." -- name: ANNOTATION_UNUSED_GENERIC_ALIAS - id: 71 - message: "Type alias generic parameter '{}' is not used in type annotation" +- name: CANNOT_INFER_OBJ_LIT + id: 174 + message: "Cannot infer type for {} because class composite needs an explicit target type" -- name: UNEXPECTED_ARRAY - id: 72 - message: "Expected type for array literal should be an array type, got {}" +- name: CANNOT_OVERRIDE + id: 141 + message: "{}{} in {} cannot override {}{} in {} because {}" + +- name: CAST_FAIL_UNREACHABLE + id: 336 + message: "this cast should never fail" + +- name: CAST_TO_NEVER + id: 305 + message: "Cast to 'never' is prohibited" + +- name: CATCH_DEFAULT_NOT_LAST + id: 34 + message: "Default catch clause should be the last in the try statement" + +- name: CATCH_OR_THROW_OF_INVALID_TYPE + id: 205 + message: "Argument must be an instance of '{}' or '{}'" + +- name: CIRCULAR_DEPENDENCY + id: 308 + message: "Circular dependency detected for identifier: {}" - name: CLASS_COMPOSITE_INVALID_KEY id: 73 message: "key in class composite should be either identifier or string literal" -- name: OBJECT_LITERAL_METHOD_KEY - id: 74 - message: "Method '{}' cannot be used as a key of object literal." +- name: CLASS_COMPOSITE_INVALID_TARGET + id: 63 + message: "Target type for class composite needs to be an object type, found '{}'" -- name: FOROF_CANT_INFER_SOURCE - id: 75 - message: "Cannot determine source expression type in the 'for-of' statement." +- name: CLASS_COMPOSITE_UNKNOWN_TYPE + id: 62 + message: "need to specify target type for class composite" -- name: FOROF_SOURCE_NONITERABLE - id: 76 - message: "'For-of' statement source expression is not of iterable type." +- name: CLASS_OR_IFACE_AS_OBJ + id: 294 + message: "Class or interface '{}' cannot be used as object" -- name: STATIC_METHOD_INVALID_MODIFIER - id: 77 - message: "Invalid method modifier(s): a static method can't have abstract, final or override modifier." +- name: COALESCE_NOT_REF + id: 117 + message: "Left-hand side of nullish-coalescing expression must be a reference type." -- name: VOID_VALUE - id: 78 - message: "Cannot use type 'void' as value. " +- name: CONFLICTING_GENERIC_INTERFACE_IMPLS + id: 181 + message: "Implements generic interface '{}' with different instantiations." -- name: EXTENSION_NAME_CONFLICT_WITH_FIELD - id: 79 - message: "The extension accessor or extension function '{}' has the same name with field of class {}" +- name: CONSTANT_FLOATING_POINT_COVERSION + id: 344 + message: "Floating-point value cannot be converted" -- name: EXTENSION_NAME_CONFLICT_WITH_METHOD - id: 80 - message: "The extension accessor '{}' has the same name with method in class {}" +- name: CONSTANT_VALUE_OUT_OF_RANGE + id: 345 + message: "Value is out of range" -- name: EXTENSION_FUNC_NAME_CONFLICT_WITH_METH - id: 81 - message: "The extension function '{}' has the same name with public method in class {}" +- name: CONST_WITHOUT_INIT + id: 363 + message: "Missing initializer in const declaration" -- name: EXTENSION_FUNC_ON_INEXETENSIBLE - id: 82 - message: "Extension function can only defined for class, interface or array." +- name: CTOR_CLASS_NOT_FIRST + id: 201 + message: "Call to '{}' must be first statement in constructor" -- name: UNEXPECTED_FUNC_BODY - id: 83 - message: "Native, Abstract and Declare methods cannot have body." +- name: CTOR_MISSING_SUPER_CALL + id: 192 + message: "Must call super constructor" -- name: NATIVE_WITH_BODY - id: 84 - message: "Native constructor declaration cannot have a body." +- name: CTOR_REF_INVALID_CTX_GLOBAL + id: 203 + message: "Cannot reference '{}' in this context." -- name: SETTER_NONVOID - id: 85 - message: "Setter must have void return type" +- name: CTOR_REF_IN_STATIC_CTX + id: 202 + message: "'{}' cannot be referenced from a static context" -- name: GETTER_VOID - id: 86 - message: "Getter must return a value" +- name: CYCLIC_ALIAS + id: 311 + message: "Circular type alias reference" -- name: PROPERTY_NONEXISTENT - id: 87 - message: "Property '{}' does not exist on type '{}'" +- name: CYCLIC_ALIAS_2 + id: 313 + message: "Type alias {} circularly refences itself" -- name: MAIN_BAD_RETURN - id: 88 - message: "Bad return type, main enable only void or int type." +- name: CYCLIC_CALLEE + id: 381 + message: "Circular call function" -- name: UNEXPECTED_VALUE_RETURN - id: 89 - message: "Unexpected return value, enclosing method return type is void." +- name: CYCLIC_CLASS_SUPER_TYPE + id: 380 + message: "Class's super type is itself" -- name: RETURN_TYPE_MISMATCH - id: 90 - message: "Return statement type is not compatible with the enclosing method's return type." +- name: CYCLIC_INHERITANCE + id: 310 + message: "Cyclic inheritance involving {}." -- name: ARROW_TYPE_MISMATCH - id: 91 - message: "Type '{}' is not compatible with the enclosing method's return type '{}'" +- name: CYCLIC_TYPE_OF + id: 379 + message: "Circular type of reference" -- name: MIXED_VOID_NONVOID - id: 92 - message: "All return statements in the function should be empty or have a value." +- name: CYCLIC_VAR_REF + id: 314 + message: "'{}' is referenced directly or indirectly in its own initializer ot type annotation." -- name: UNEXPECTED_VOID - id: 93 - message: "'{}' shouldn't have void return type." +- name: DEFAULT_DYNAMIC_IMPORT + id: 352 + message: "Default import is currently not implemented in dynamic import" -- name: UNEXPECTED_NONVOID - id: 94 - message: "'{}' should have void return type." +- name: DEFAULT_EXPORT_DIRECT_IMPORTED + id: 353 + message: "Use the default import syntax to import a default exported element" -- name: MISSING_RETURN_TYPE_2 - id: 95 - message: "'{}' doesn't have return type." +- name: DEFAULT_IMPORT_NOT_FOUND + id: 358 + message: "Cannot find default imported element in the target" -- name: RETURN_ISNT_ITERATOR - id: 96 - message: "The return type of '{}' must be a type that implements Iterator interface." +- name: DIFFERENT_SUBSEQ_DECL + id: 316 + message: "Subsequent variable declaration must have the same type. Variable '{}' must be of type '{}', but here has type + '{}'." -- name: INVALID_CONST_ASSIGNMENT - id: 97 - message: "Cannot assign a value to a constant variable {}" +- name: DIFFERENT_SUBSEQ_PROP_DECL + id: 317 + message: "Subsequent variable declaration must have the same type. Variable '{}' must be of type '{}', but here has type + '{}'." -- name: INVALID_READONLY_ASSIGNMENT - id: 98 - message: "Cannot assign a value to a readonly variable {}" +- name: DISJOINT_CONVERSION + id: 322 + message: "Conversion of type '{}' to type '{}' may be a mistake because neither type sufficiently overlaps with the other. + If this was intentional, convert the expression to 'unknown' first." -- name: ITERATOR_TYPE_ABSENT - id: 99 - message: "Cannot obtain iterator type in 'for-of' statement." -- name: OBJ_LIT_PROPERTY_REDECLARATION - id: 100 - message: "An object literal cannot have multiple properties with the same name." +- name: DUPLICATE_ACCESSOR + id: 219 + message: "Duplicate accessor definition" -- name: INIT_DOESNT_COMPLETE - id: 101 - message: "Initializer must be able to complete normally." +- name: DUPLICATE_OVERLOADED_NAME + id: 385 + message: "Duplicate overloaded method." + +- name: DUPLICATE_TYPE_PARAM + id: 182 + message: "Duplicate type parameter '{}'." + +- name: DYMANIC_INIT_WITH_OBJEXPR + id: 382 + message: "Dymanic Type {} cannot be initialize with an object expression" + +- name: ENUMB_REFERENCE_VIA_VAR + id: 239 + message: "Cannot refer to enum members through variable." + +- name: ENUM_CONST_MISSING_PROP + id: 240 + message: "Enum constant does not have property '{}'." + +- name: ENUM_INVALID_DISCRIMINANT + id: 162 + message: "Incompatible types. Found: {}, required: char , byte , short , int, long , Char , Byte , Short , Int, Long , String + or an enum type" + +- name: ENUM_NO_SUCH_CONST + id: 241 + message: "No enum constant named '{}' in enum '{}'" + +- name: ENUM_NO_SUCH_METHOD + id: 242 + message: "No enum item method called '{}'" + +- name: ENUM_NO_SUCH_STATIC_METHOD + id: 243 + message: "No enum type method called '{}'" + +- name: ENUM_REFERENCE_VIA_ALIAS + id: 238 + message: "Cannot refer to enum members through type alias." + +- name: ENUM_TYPE_INVALID + id: 35 + message: "Invalid enumeration value type." + +- name: ERROR_ARKTS_NO_DECLARATION_MERGING + id: 341 + message: "Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in + the codebase!" + +- name: ERROR_ARKTS_NO_ENUM_MIXED_TYPES + id: 342 + message: "Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type." + +- name: ERROR_ARKTS_NO_LITERAL_INITIALIZATION_WITHOUT_PARAMETERLESS_CONSTRUCTOR + id: 340 + message: "Initialization with literals is not supported if the type has no parameterless constructor. Declare the parameterless + constructor explicitly or remove parametered constructors!" + +- name: ERROR_ARKTS_NO_PROPERTIES_BY_INDEX + id: 343 + message: "Indexed signatures are not allowed. Use arrays instead!" + +- name: EXCEPTION_REDECLARATION + id: 13 + message: "Redeclaration of exception type" + +- name: EXPECTED_TYPE_ARGUMENTS + id: 274 + message: "Expected at least {} type arguments, but got {}." + +- name: EXPORT_INCORRECT + id: 361 + message: "Incorrect export '{}'" + +- name: EXPR_NONCONSTRUCTIBLE + id: 292 + message: "This expression is not constructible." + +- name: EXPR_NOT_CALLABLE + id: 289 + message: "This expression is not callable." + +- name: EXTENDING_FINAL + id: 178 + message: "Cannot inherit with 'final' modifier." + +- name: EXTENDING_STRUCT + id: 177 + message: "struct {} is not extensible." + +- name: EXTENDING_UTILITY_TYPE + id: 176 + message: "The super type of '{}' class is not extensible." + +- name: EXTENDS_NON_OBJECT + id: 185 + message: "Extends constraint must be an object" - name: EXTEND_DYNAMIC id: 102 message: "Class {} shouldn't extend dynamic class." -- name: MISSING_RETURN_STMT - id: 103 - message: "Function with a non void return type must return a value." +- name: EXTENSION_ACCESSOR_INVALID_CALL + id: 59 + message: "Extension accessor can't be used as a method call or function call." -- name: NONRETURNING_PATHS - id: 104 - message: "Not all code paths return a value." +- name: EXTENSION_FUNC_NAME_CONFLICT_WITH_METH + id: 81 + message: "The extension function '{}' has the same name with public method in class {}" -- name: BINOP_INVALID_TYPE - id: 105 - message: "Operator '{}' cannot be applied to types '{}' and '{}'." +- name: EXTENSION_FUNC_ON_INEXETENSIBLE + id: 82 + message: "Extension function can only defined for class, interface or array." -- name: BINOP_ON_UNION - id: 106 - message: "Bad operand type: multiple types left in the normalized union type ({}). Unions are not allowed in binary expressions except equality." +- name: EXTENSION_GETTER_INVALID_CTX + id: 269 + message: "Extension getter in wrong usage" -- name: OP_NONNUMERIC - id: 107 - message: "Bad operand type, the types of the operands must be numeric type." +- name: EXTENSION_NAME_CONFLICT_WITH_FIELD + id: 79 + message: "The extension accessor or extension function '{}' has the same name with field of class {}" -- name: BINOP_NONARITHMETIC_TYPE - id: 108 - message: "Bad operand type, the types of the operands must be numeric type, enum or String." +- name: EXTENSION_NAME_CONFLICT_WITH_METHOD + id: 80 + message: "The extension accessor '{}' has the same name with method in class {}" -- name: BINOP_UNION - id: 109 - message: "Bad operand type, unions are not allowed in binary expressions except equality." +- name: FIELD_ASSIGN_TYPE_MISMATCH + id: 298 + message: "Cannot assign to a {} variable {}" -- name: BINOP_NOT_LOGICAL - id: 110 - message: "Bad operand type, the types of the operands must be of possible condition type." +- name: FIELD_REASSIGNMENT + id: 297 + message: "Cannot reassign {} {}" -- name: BINOP_NOT_REFERENCE - id: 111 - message: "Both operands have to be reference types" +- name: FINAL_METHOD_INVALID_MODIFIER + id: 48 + message: "Invalid method modifier(s): a final method can't have abstract or static modifier." -- name: BINOP_DYN_UNIMPLEMENTED - id: 112 - message: "Unimplemented case in dynamic type comparison." +- name: FIXED_ARRAY_PARAM_ERROR + id: 277 + message: "FixedArray must have only one type parameter." -- name: BINOP_MISMATCHED_ENUMS - id: 113 - message: "Bad operand type, the types of the operands must be the same enum type." +- name: FLOW_REDIRECTION_INVALID_CTX + id: 161 + message: "Control flow redirection statement can not be used out of loop or switch statement." -- name: BINOP_INCOMPARABLE - id: 114 - message: "Bad operand type, the types of the operands must be numeric, same enumeration, or boolean type." +- name: FOROF_CANT_INFER_SOURCE + id: 75 + message: "Cannot determine source expression type in the 'for-of' statement." -- name: BINOP_NOT_SAME - id: 115 - message: "Bad operand type, the types of the operands must be same type." +- name: FOROF_SOURCE_NONITERABLE + id: 76 + message: "'For-of' statement source expression is not of iterable type." -- name: INSTANCEOF_NOT_TYPE - id: 116 - message: "Right-hand side of instanceof expression must represent a type." +- name: FUNCTION_REDECLERATION + id: 160 + message: "Function '{}{}' is redeclared with different signature '{}{}'" -- name: COALESCE_NOT_REF - id: 117 - message: "Left-hand side of nullish-coalescing expression must be a reference type." +- name: FUNCTION_REDECL_BY_ASM_SIG + id: 131 + message: "Function {} with this assembly signature already declared." -- name: BINOP_UNEXPECTED_ERROR - id: 118 - message: "Unexpected type error in binary expression" +- name: FUNCTION_REDECL_BY_TYPE_SIG + id: 130 + message: "Function {} is already declared." -- name: ANALYSIS_ERRORS - id: 119 - message: "There were errors during assign analysis ({})" +- name: FUNCTION_WITHOUT_BODY + id: 17 + message: "Only abstract or native methods can't have body." -- name: INFERENCE_TYPE_INCOMPAT - id: 120 - message: "{} is not compatible with type {}" +- name: FUNC_EXPR_INVALID + id: 16 + message: "Invalid function expression" -- name: SPREAD_ONTO_SINGLE_PARAM - id: 121 - message: "Spread argument cannot be passed for ordinary parameter." +- name: GENERIC_ALIAS_PARAM_COUNT_MISMATCH + id: 157 + message: "Wrong number of type parameters for generic type alias" -- name: ARG_IS_CLASS_ID - id: 122 - message: "Class name can't be the argument of function or method." +- name: GENERIC_ALIAS_WITHOUT_PARAMS + id: 155 + message: "Type alias declaration is generic, but too few type arguments were provided" -- name: MULTIPLE_SPREADS - id: 123 - message: "Spread argument for the rest parameter can be only one." +- name: GENERIC_ERROR_OR_EXCEPTION + id: 214 + message: "Generics are not allowed as '{}' or '{}' subclasses." -- name: PARAM_COUNT_MISMATCH - id: 124 - message: "Expected {} arguments, got {}." +- name: GENERIC_TYPE_PARAM_COUNT_MISMATCH + id: 171 + message: "Type '{}' has {} number of type parameters, but {} type arguments were provided." -- name: NO_SUCH_PARAMLESS_CTOR - id: 125 - message: "No matching parameterless constructor" +- name: GENERIC_WITHOUT_TYPE_PARAMS + id: 170 + message: "Type '{}' is generic but type argument were not provided." -- name: AMBIGUOUS_FUNC_REF - id: 126 - message: "Reference to {} is ambiguous" +- name: GETTER_MISSING_IMPL + id: 188 + message: "{} is not abstract and does not implement getter for {} property in {}" -- name: NO_MATCHING_SIG - id: 127 - message: "No matching {} signature for {}" +- name: GETTER_VOID + id: 86 + message: "Getter must return a value" -- name: NO_MATCHING_SIG_2 - id: 128 - message: "No matching {} signature" +- name: ID_IN_WRONG_CTX + id: 144 + message: "{} name '{}' used in the wrong context" -- name: AMBIGUOUS_CALL_2 - id: 129 - message: "Call to `{}` is ambiguous " +- name: ID_REDECLARED + id: 369 + message: "Identifier '{}' has already been declared." -- name: FUNCTION_REDECL_BY_TYPE_SIG - id: 130 - message: "Function {} is already declared." +- name: ID_WRONG_CTX + id: 330 + message: "Identifier '{}' is used in wrong context." -- name: FUNCTION_REDECL_BY_ASM_SIG - id: 131 - message: "Function {} with this assembly signature already declared." +- name: IFACE_INVALID_EXTENDS + id: 320 + message: "Interface '{}' incorrectly extends interface '{}'" -- name: INFER_FAILURE_FUNC_PARAM - id: 132 - message: "The type of parameter '{}' cannot be inferred" +- name: IFACE_MULTIPLE_EXTENSION + id: 315 + message: "Interface '{}' cannot simultaneously extend types '{}' and '{}'." -- name: MAIN_INVALID_ARG_COUNT - id: 133 - message: "0 or 1 argument are allowed" +- name: ILLEGAL_NON_NULLISH_TYPE + id: 339 + message: "Only type parameters can be used as a nonnullish type" -- name: MAIN_WITH_REST - id: 134 - message: "Rest parameter is not allowed in the 'main' function." +- name: ILLEGAL_UNARY_OP + id: 11 + message: "Illegal unary operator." -- name: MAIN_PARAM_NOT_ARR_OF_STRING - id: 135 - message: "Only 'FixedArray' type argument is allowed." +- name: IMPORTED_NOT_EXPORTED + id: 355 + message: "Imported element not exported '{}'" -- name: OVERRIDE_DOESNT_OVERRIDE - id: 136 - message: "Method {}{} in {} not overriding any method" +- name: IMPORTING_NONEXPORTED_TYPE + id: 354 + message: "Cannot import '{}', imported type imports only exported types." -- name: SIG_UNAVAILABLE - id: 137 - message: "Signature is not available here." +- name: IMPORT_ARG_NOT_STRING + id: 302 + message: "'import' expressions require string as argument." -- name: THIS_OUTSIDE_METHOD_CTX - id: 138 - message: "Cannot reference 'this' in this context." +- name: IMPORT_NOT_FOUND + id: 356 + message: "Cannot find imported element '{}'" -- name: SIG_INVISIBLE - id: 139 - message: "Signature {}{} is not visible here." +- name: IMPORT_NOT_FOUND_2 + id: 360 + message: "Cannot find import: {}" -- name: NO_SUCH_SIG_WITH_TRAILING_LAMBDA - id: 140 - message: "No matching call signature with trailing lambda" +- name: IMPORT_RENAMES_ANNOTATION + id: 357 + message: "Can not rename annotation '{}' in export or import statements." -- name: CANNOT_OVERRIDE - id: 141 - message: "{}{} in {} cannot override {}{} in {} because {}" +- name: INDEX_NEGATIVE_OR_FRACTIONAL + id: 248 + message: "Index value cannot be less than zero or fractional." -- name: AMBIGUOUS_CALL - id: 142 - message: "Call to `{}` is ambiguous as `2` versions of `{}` are available: `{}{}` and `{}{}`" +- name: INDEX_NONINTEGRAL_FLOAT + id: 197 + message: "Index fractional part should be zero." -- name: UNRESOLVED_REF - id: 143 - message: "Unresolved reference {}" +- name: INDEX_ON_INVALID_TYPE + id: 252 + message: "Indexed access is not supported for such expression type." -- name: ID_IN_WRONG_CTX - id: 144 - message: "{} name '{}' used in the wrong context" +- name: INDEX_OOB + id: 249 + message: "Index value cannot be greater than or equal to the array size." -- name: PROP_ACCESS_WITHOUT_THIS - id: 145 - message: "Property '{}' must be accessed through 'this'" +- name: INFERENCE_TYPE_INCOMPAT + id: 120 + message: "{} is not compatible with type {}" -- name: PROPERTY_CAPTURE - id: 146 - message: "Property '{}' of enclosing class '{}' is not allowed to be captured from the local class '{}'" +- name: INFER_FAILURE_FUNC_PARAM + id: 132 + message: "The type of parameter '{}' cannot be inferred" -- name: PROPERTY_CAPTURE_IN_STATIC - id: 147 - message: "Not allowed to capture variable '{}' in static method" +- name: INFER_FAIL_FOR_LAMBDA_SIG + id: 254 + message: "Cannot deduce call signature" -- name: INVALID_EXPR_IN_RETURN - id: 148 - message: "Invalid return statement expression" +- name: INFER_FAIL_ON_LAMBDA + id: 237 + message: "Cannot infer arrow function type from context for type: '{}', consider adding type explicitly" -- name: INVALID_RETURN_FUNC_EXPR - id: 149 - message: "Invalid return function expression" +- name: INFER_FAIL_ON_PARAM + id: 222 + message: "The type of parameter '{}' cannot be inferred." -- name: RETURN_DIFFERENT_PRIM - id: 150 - message: "Function cannot have different primitive return types, require '{}', found '{}'" +- name: INHERITED_CLASS_TYPE_MISMATCH + id: 216 + message: "Cannot inherit from class {}, because {} {} is inherited with a different declaration type" -- name: MEMBER_OF_OBJECT_LIT - id: 151 - message: "Class composite must be constructed separately before referring their members." +- name: INHERITED_INTERFACE_TYPE_MISMATCH + id: 215 + message: "Cannot inherit from interface {} because {} {} is inherited with a different declaration type" -- name: TYPE_MISMATCH_ENUM - id: 152 - message: "Cannot assign type '{}' for variable {}." +- name: INIT_DOESNT_COMPLETE + id: 101 + message: "Initializer must be able to complete normally." - name: INIT_IN_AMBIENT id: 153 message: "Initializers are not allowed in ambient contexts: {}" -- name: AMBIGUOUS_FUNC_INIT - id: 154 - message: "Ambiguous function initialization because of multiple overloads" +- name: INNER_CLASS_MUTABLE_STATIC_PROP + id: 196 + message: "Inner class cannot have non-readonly static properties" -- name: GENERIC_ALIAS_WITHOUT_PARAMS - id: 155 - message: "Type alias declaration is generic, but too few type arguments were provided" +- name: INNER_CLASS_WITH_STATIC_METH + id: 195 + message: "Inner class cannot have static methods" -- name: NON_GENERIC_ALIAS_WITH_PARAMS - id: 156 - message: "Type alias declaration is not generic, but type parameters were provided" +- name: INSTANCEOF_NONOBJECT + id: 296 + message: "Using the 'instance of' operator with non-object type '{}'" -- name: GENERIC_ALIAS_PARAM_COUNT_MISMATCH - id: 157 - message: "Wrong number of type parameters for generic type alias" +- name: INSTANCEOF_NOT_TYPE + id: 116 + message: "Right-hand side of instanceof expression must represent a type." -- name: NAMESPACE_AS_TYPE - id: 158 - message: "Namespace '{}' cannot be used as a type." +- name: INTERFACE_EXTENDS_CLASS + id: 378 + message: "Interfaces cannot extend classes, only other interfaces." -- name: ANNOTATION_AS_TYPE - id: 159 - message: "Annotations cannot be used as a type." +- name: INTERFACE_INSTANTIATION + id: 275 + message: "{} is an interface therefore cannot be instantiated." -- name: FUNCTION_REDECLERATION - id: 160 - message: "Function '{}{}' is redeclared with different signature '{}{}'" +- name: INTERFACE_METHOD_COLLISION + id: 187 + message: "Method '{}' is declared in {} and {} interfaces." -- name: FLOW_REDIRECTION_INVALID_CTX - id: 161 - message: "Control flow redirection statement can not be used out of loop or switch statement." +- name: INTERFACE_PROPERTY_REQUIRES_SETTER + id: 337 + message: "Cannot implement interface {}: property '{}' must have a setter, but the implementation is readonly" + +- name: INTERFACE_PROP_NOT_PUBLIC + id: 217 + message: "Interface property implementation cannot be generated as non-public" -- name: ENUM_INVALID_DISCRIMINANT - id: 162 - message: "Incompatible types. Found: {}, required: char , byte , short , int, long , Char , Byte , Short , Int, Long , String or an enum type" +- name: INTERFACE_REDECLARED + id: 372 + message: "Interface redeclaration is not allowed" -- name: NOT_CONSTANT - id: 163 - message: "Constant expression required" +- name: INTERFACE_WITH_METHOD + id: 256 + message: "Interface has methods" -- name: SWITCH_CASE_INVALID_TYPE - id: 164 - message: "Unexpected type {}" +- name: INVALID_ANNOTATION_RETENTION + id: 3 + message: Annotation '@Retention' can only be applied to annotation declarations. -- name: SWITCH_CASE_DUPLICATE - id: 165 - message: "Case duplicate" +- name: INVALID_ASSIGNMNENT + id: 318 + message: "Type '{}' cannot be assigned to type '{}'" -- name: SWITCH_CASE_VAR_DUPLICATE_VAL - id: 166 - message: "Variable has same value with another switch case" +- name: INVALID_ASSIGNMNENT_2 + id: 321 + message: "Type '{}' is not assignable to type '{}'." -- name: INVALID_TYPE_PARAM - id: 168 - message: "Type '{}' is not valid for generic type arguments" +- name: INVALID_CAPTURE + id: 366 + message: "Cannot capture variable '{}'." -- name: NOT_GENERIC - id: 169 - message: "Type '{}' is not generic." +- name: INVALID_CAST + id: 326 + message: "Cannot cast type '{}' to '{}'" -- name: GENERIC_WITHOUT_TYPE_PARAMS - id: 170 - message: "Type '{}' is generic but type argument were not provided." +- name: INVALID_CONST_ASSIGNMENT + id: 97 + message: "Cannot assign a value to a constant variable {}" -- name: GENERIC_TYPE_PARAM_COUNT_MISMATCH - id: 171 - message: "Type '{}' has {} number of type parameters, but {} type arguments were provided." +- name: INVALID_DOT_CLASS + id: 21 + message: "Invalid .class reference" -- name: NO_STATIC_INVOKE - id: 172 - message: "No static {} method and static {} method in {}. {}() is not allowed." +- name: INVALID_EXPORT + id: 367 + message: "Invalid exported binding" -- name: STATIC_PROP_INVALID_CTX - id: 173 - message: "Static property '{}' must be accessed through it's class '{}'" +- name: INVALID_EXPR_IN_RETURN + id: 148 + message: "Invalid return statement expression" -- name: CANNOT_INFER_OBJ_LIT - id: 174 - message: "Cannot infer type for {} because class composite needs an explicit target type" +- name: INVALID_INDEX_TYPE + id: 236 + message: "Type '{}' cannot be used as an index type. Only primitive or unboxable integral types can be used as index." -- name: AMBIENT_CONST_INVALID_LIT - id: 175 - message: "A 'const' initializer in an ambient context must be a string or numeric literal: {}" +- name: INVALID_LAMBDA_PARAMETER + id: 395 + message: "Invalid lambda parameter. Expected: 'identifier(: type)?', 'identifier?(: type)?' or '...identifier(: type)?'." -- name: EXTENDING_UTILITY_TYPE - id: 176 - message: "The super type of '{}' class is not extensible." +- name: INVALID_READONLY_ASSIGNMENT + id: 98 + message: "Cannot assign a value to a readonly variable {}" -- name: EXTENDING_STRUCT - id: 177 - message: "struct {} is not extensible." +- name: INVALID_RECORD_PROPERTY + id: 393 + message: "Invalid record property" -- name: EXTENDING_FINAL - id: 178 - message: "Cannot inherit with 'final' modifier." +- name: INVALID_RETURN_FUNC_EXPR + id: 149 + message: "Invalid return function expression" -- name: NOT_INTERFACE - id: 179 - message: "Interface expected here." +- name: INVALID_SPREAD_IN_TUPLE + id: 55 + message: "'{}' cannot be spread in tuple." -- name: REPEATED_INTERFACE - id: 180 - message: "Repeated interface." +- name: INVALID_TYPE_PARAM + id: 168 + message: "Type '{}' is not valid for generic type arguments" -- name: CONFLICTING_GENERIC_INTERFACE_IMPLS - id: 181 - message: "Implements generic interface '{}' with different instantiations." +- name: INVALID_TYPE_REF + id: 299 + message: "Invalid type reference." -- name: DUPLICATE_TYPE_PARAM - id: 182 - message: "Duplicate type parameter '{}'." +- name: INVISIBLE_INDEX_ACCESSOR + id: 268 + message: "Index access method is not visible here." -- name: TYPE_PARAM_USE_BEFORE_DEFINE - id: 183 - message: "Type Parameter {} should be defined before use." +- name: INVISIBLE_ITERATOR + id: 272 + message: "Iterator method is not visible here." -- name: TYPE_PARAM_CIRCULAR_CONSTRAINT - id: 184 - message: "Type parameter '{}' has circular constraint dependency." +- name: ITERATOR_DOESNT_RETURN_ITERABLE + id: 261 + message: "Iterator method must return an object which implements Iterator" -- name: EXTENDS_NON_OBJECT - id: 185 - message: "Extends constraint must be an object" +- name: ITERATOR_ELEMENT_TYPE_MISMATCH + id: 69 + message: "Source element type '{}' is not assignable to the loop iterator type '{}'." -- name: ABSTRACT_IS_FINAL - id: 186 - message: "Cannot use both 'final' and 'abstract' modifiers." +- name: ITERATOR_MISSING_NEXT + id: 260 + message: "Iterator object doesn't have proper next method." -- name: INTERFACE_METHOD_COLLISION - id: 187 - message: "Method '{}' is declared in {} and {} interfaces." +- name: ITERATOR_TYPE_ABSENT + id: 99 + message: "Cannot obtain iterator type in 'for-of' statement." -- name: GETTER_MISSING_IMPL - id: 188 - message: "{} is not abstract and does not implement getter for {} property in {}" +- name: KEYOF_REFERENCE_TYPE + id: 276 + message: "The `keyof` keyword can only be used for class or interface type." -- name: SETTER_MISSING_IMPL - id: 189 - message: "{} is not abstract and does not implement setter for {} property in {}" +- name: LATE_INITIALIZATION_FIELD_HAS_INVALID_TYPE + id: 376 + message: "Late-initialized field cannot be nullish types or possibly nullish types." -- name: MISSING_OVERRIDE_OF_ABSTRACT_METH - id: 190 - message: "{} is not abstract and does not override abstract method {}{} in {}" - code_fix_ids: [FixClassNotImplementingInheritedMembers] - name: LOCAL_CLASS_INVALID_CTX id: 191 message: "Local classes must be defined between balanced braces" -- name: CTOR_MISSING_SUPER_CALL - id: 192 - message: "Must call super constructor" +- name: LOCAL_CLASS_NATIVE_METHOD + id: 278 + message: "Local class '{}' shouldn't have native methods/constructors" + +- name: MAIN_BAD_RETURN + id: 88 + message: "Bad return type, main enable only void or int type." + +- name: MAIN_INVALID_ARG_COUNT + id: 133 + message: "0 or 1 argument are allowed" + +- name: MAIN_PARAM_NOT_ARR_OF_STRING + id: 135 + message: "Only 'FixedArray' type argument is allowed." + +- name: MAIN_WITH_REST + id: 134 + message: "Rest parameter is not allowed in the 'main' function." - name: MAYBE_DOUBLE_INIT id: 193 @@ -777,269 +875,224 @@ semantic: id: 194 message: "Variable '{}' might not have been initialized" -- name: INNER_CLASS_WITH_STATIC_METH - id: 195 - message: "Inner class cannot have static methods" - -- name: INNER_CLASS_MUTABLE_STATIC_PROP - id: 196 - message: "Inner class cannot have non-readonly static properties" - -- name: INDEX_NONINTEGRAL_FLOAT - id: 197 - message: "Index fractional part should be zero." - -- name: TUPLE_INDEX_OOB - id: 198 - message: "Element accessor value is out of tuple size bounds." - -- name: TUPLE_INDEX_NONCONST - id: 199 - message: "Only constant expression allowed for element access on tuples." - -- name: TUPLE_INDEX_NOT_INT - id: 200 - message: "Only integer type allowed for element access on tuples." - -- name: CTOR_CLASS_NOT_FIRST - id: 201 - message: "Call to '{}' must be first statement in constructor" - -- name: CTOR_REF_IN_STATIC_CTX - id: 202 - message: "'{}' cannot be referenced from a static context" - -- name: CTOR_REF_INVALID_CTX_GLOBAL - id: 203 - message: "Cannot reference '{}' in this context." - -- name: NO_SUCH_CTOR_SIG - id: 204 - message: "No matching call signature for constructor" - -- name: CATCH_OR_THROW_OF_INVALID_TYPE - id: 205 - message: "Argument must be an instance of '{}' or '{}'" - -- name: NOT_EXPORTED - id: 206 - message: "'{}' is not exported in '{}'" - -- name: PROP_IS_STATIC - id: 207 - message: "'{}' is a static property of '{}'" - -- name: PROP_NOT_STATIC - id: 208 - message: "'{}' is an instance property of '{}'" +- name: MEMBER_OF_OBJECT_LIT + id: 151 + message: "Class composite must be constructed separately before referring their members." -- name: ASSIGN_TO_READONLY_PROP - id: 209 - message: "Cannot assign to this property because it is readonly." +- name: MEMBER_TYPE_MISMATCH_ACROSS_UNION + id: 244 + message: "Member type must be the same for all union objects." -- name: READONLY_FIELD_MULTIPLE_INIT - id: 210 - message: "Readonly field already initialized at declaration." +- name: MERGED_DECLS + id: 370 + message: "Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in + the codebase!" -- name: READ_FROM_WRITEONLY_PROP - id: 211 - message: "Cannot read from this property because it is writeonly." +- name: METHOD_ACCESSOR_COLLISION + id: 218 + message: "Method cannot use the same name as {} accessor property" -- name: UNDEFINED_METHOD - id: 212 - message: "Method {} does not exist on this type." +- name: METHOD_ASSIGNMENT + id: 394 + message: "Class methods cannot be overwritten." - name: METHOD_WRONG_CTX id: 213 message: "Method used in wrong context" -- name: GENERIC_ERROR_OR_EXCEPTION - id: 214 - message: "Generics are not allowed as '{}' or '{}' subclasses." +- name: MISSING_EXTENSION_ACCESSOR + id: 246 + message: "Can't find the extension accessor." -- name: INHERITED_INTERFACE_TYPE_MISMATCH - id: 215 - message: "Cannot inherit from interface {} because {} {} is inherited with a different declaration type" +- name: MISSING_INDEX_ACCESSOR_WITH_SIG + id: 251 + message: "Cannot find index access method with the required signature." -- name: INHERITED_CLASS_TYPE_MISMATCH - id: 216 - message: "Cannot inherit from class {}, because {} {} is inherited with a different declaration type" +- name: MISSING_INIT_FOR_PARAM + id: 253 + message: "Expected initializer for parameter {}." -- name: INTERFACE_PROP_NOT_PUBLIC - id: 217 - message: "Interface property implementation cannot be generated as non-public" +- name: MISSING_ITERATOR_METHOD + id: 258 + message: "Object type doesn't have proper iterator method." -- name: METHOD_ACCESSOR_COLLISION - id: 218 - message: "Method cannot use the same name as {} accessor property" +- name: MISSING_ITERATOR_METHOD_WITH_SIG + id: 259 + message: "Cannot find iterator method with the required signature." -- name: DUPLICATE_ACCESSOR - id: 219 - message: "Duplicate accessor definition" +- name: MISSING_OVERRIDE_OF_ABSTRACT_METH + id: 190 + message: "{} is not abstract and does not override abstract method {}{} in {}" + code_fix_ids: [FixClassNotImplementingInheritedMembers] -- name: ACCESSORS_MOD_MISMATCH - id: 220 - message: "Getter and setter methods must have the same accessor modifiers" +- name: MISSING_RETURN_STMT + id: 103 + message: "Function with a non void return type must return a value." -- name: STATIC_METH_IN_CLASS_AND_INTERFACE - id: 221 - message: "Static {} method and static {} method both exist in class/interface {} is not allowed." +- name: MISSING_RETURN_TYPE + id: 18 + message: "Native and Declare methods should have explicit return type." -- name: INFER_FAIL_ON_PARAM - id: 222 - message: "The type of parameter '{}' cannot be inferred." +- name: MISSING_RETURN_TYPE_2 + id: 95 + message: "'{}' doesn't have return type." -- name: UTIL_TYPE_INVALID_TYPE_PARAM_COUNT - id: 223 - message: "Invalid number of type parameters for {} type, should be 1." +- name: MIXED_VOID_NONVOID + id: 92 + message: "All return statements in the function should be empty or have a value." -- name: UTIL_TYPE_OF_NONREFERENCE - id: 224 - message: "Only reference types can be converted to utility types." +- name: MODULE_INDEX_MISSING + id: 359 + message: "Cannot find index.[ets|ts] or package module in folder: {}" -- name: UTILITY_TYPE_UNIMPLEMENTED - id: 225 - message: "This utility type is not yet implemented." +- name: MULTIPLE_DEFAULT_EXPORTS + id: 374 + message: "Only one default export is allowed in a module" -- name: REQUIRED_PROP_MISSING_INIT - id: 226 - message: "Class property '{}' needs to be initialized for Required<{}>." +- name: MULTIPLE_SPREADS + id: 123 + message: "Spread argument for the rest parameter can be only one." -- name: ARRAY_ELEMENT_INIT_TYPE_INCOMPAT - id: 227 - message: "Array element at index {} with type '{}' is not compatible with the target array element type '{}'" +- name: NAMESPACE_AS_TYPE + id: 158 + message: "Namespace '{}' cannot be used as a type." -- name: TYPEARG_TYPEPARAM_SUBTYPING - id: 228 - message: "Type argument '{}' should be a subtype of '{}'-constraint" +- name: NAMESPACE_CALL + id: 295 + message: "Namespace style identifier {} is not callable." -- name: OVERLOADED_FUNCTION_REFERENCE - id: 229 - message: "Overloaded function identifier '{}' can not be used as value" +- name: NATIVE_WITHOUT_RETURN + id: 15 + message: "'Native' method should have explicit return type" -- name: ANNOT_WITHOUT_AT - id: 230 - message: "Annotation missing '@' symbol before annotation name." +- name: NATIVE_WITH_BODY + id: 84 + message: "Native constructor declaration cannot have a body." -- name: TUPLE_WRONG_NUMBER_OF_ELEMS - id: 231 - message: "Initializer has {} elements, but tuple requires {}" +- name: NEGATIVE_INDEX + id: 247 + message: "Index value cannot be less than zero." -- name: ANNOT_IS_VOID - id: 232 - message: "'void' used as type annotation." +- name: NONEXISTENT_TYPE + id: 70 + message: "'{}' type does not exist." -- name: THIS_OR_SUPER_IN_CTOR - id: 235 - message: "Using {} is not allowed in constructor" +- name: NONLITERAL_INSTANTIATION + id: 53 + message: "Required type can be instantiated only with object literal" -- name: INVALID_INDEX_TYPE - id: 236 - message: "Type '{}' cannot be used as an index type. Only primitive or unboxable integral types can be used as index." +- name: NONRETURNING_PATHS + id: 104 + message: "Not all code paths return a value." -- name: INFER_FAIL_ON_LAMBDA - id: 237 - message: "Cannot infer arrow function type from context for type: '{}', consider adding type explicitly" +- name: NON_GENERIC_ALIAS_WITH_PARAMS + id: 156 + message: "Type alias declaration is not generic, but type parameters were provided" -- name: ENUM_REFERENCE_VIA_ALIAS - id: 238 - message: "Cannot refer to enum members through type alias." +- name: NON_SUPERTYPE_OF_UNDEFINED_AS_ARRAY_ELEMENT_TYPE + id: 51 + message: "Cannot use array creation expression with non-constructable element type which is non-assignable from undefined." -- name: ENUMB_REFERENCE_VIA_VAR - id: 239 - message: "Cannot refer to enum members through variable." +- name: NON_VOID_RETURN_IN_CONSTRUCTOR + id: 33 + message: "Return statement with expression isn't allowed in constructor." -- name: ENUM_CONST_MISSING_PROP - id: 240 - message: "Enum constant does not have property '{}'." +- name: NOT_ALLOWED_THIS_IN_ARRAY_TYPE + id: 283 + message: "A 'this' cannot be used as type of array." -- name: ENUM_NO_SUCH_CONST - id: 241 - message: "No enum constant named '{}' in enum '{}'" +- name: NOT_ALLOWED_THIS_IN_TUPLE_TYPE + id: 282 + message: "A 'this' cannot be used as a part of tuple type." -- name: ENUM_NO_SUCH_METHOD - id: 242 - message: "No enum item method called '{}'" +- name: NOT_ALLOWED_THIS_IN_UNION_TYPE + id: 281 + message: "A 'this' cannot be used as a part of union type." -- name: ENUM_NO_SUCH_STATIC_METHOD - id: 243 - message: "No enum type method called '{}'" +- name: NOT_AN_ANNOTATION + id: 67 + message: "'{}' is not an annotation." -- name: MEMBER_TYPE_MISMATCH_ACROSS_UNION - id: 244 - message: "Member type must be the same for all union objects." +- name: NOT_CONSTANT + id: 163 + message: "Constant expression required" -- name: UNION_MEMBER_ILLEGAL_TYPE - id: 245 - message: "Type {} is illegal in union member expression." +- name: NOT_EXPORTED + id: 206 + message: "'{}' is not exported in '{}'" -- name: MISSING_EXTENSION_ACCESSOR - id: 246 - message: "Can't find the extension accessor." +- name: NOT_GENERIC + id: 169 + message: "Type '{}' is not generic." -- name: NEGATIVE_INDEX - id: 247 - message: "Index value cannot be less than zero." +- name: NOT_IMPLEMENTED + id: 368 + message: "not implemented" -- name: INDEX_NEGATIVE_OR_FRACTIONAL - id: 248 - message: "Index value cannot be less than zero or fractional." +- name: NOT_INTERFACE + id: 179 + message: "Interface expected here." -- name: INDEX_OOB - id: 249 - message: "Index value cannot be greater than or equal to the array size." +- name: NO_CALL_SIGNATURE + id: 2 + message: Type '{}' has no call signatures. - name: NO_INDEX_ACCESS_METHOD id: 250 message: "Object type doesn't have proper index access method." -- name: MISSING_INDEX_ACCESSOR_WITH_SIG - id: 251 - message: "Cannot find index access method with the required signature." +- name: NO_MATCHING_SIG + id: 127 + message: "No matching {} signature for {}" -- name: INDEX_ON_INVALID_TYPE - id: 252 - message: "Indexed access is not supported for such expression type." +- name: NO_MATCHING_SIG_2 + id: 128 + message: "No matching {} signature" -- name: MISSING_INIT_FOR_PARAM - id: 253 - message: "Expected initializer for parameter {}." +- name: NO_PARAMLESS_CTOR + id: 291 + message: "Type {} has no parameterless constructor. Initialization with literals is not supported if the type has no parameterless + constructor. Declare the parameterless constructor explicitly or remove parametered constructors!" -- name: INFER_FAIL_FOR_LAMBDA_SIG - id: 254 - message: "Cannot deduce call signature" +- name: NO_STATIC_INVOKE + id: 172 + message: "No static {} method and static {} method in {}. {}() is not allowed." -- name: AMBIGUOUS_UNION_TYPE_OP - id: 255 - message: "Ambiguous union type operation" +- name: NO_SUCH_CTOR_SIG + id: 204 + message: "No matching call signature for constructor" -- name: INTERFACE_WITH_METHOD - id: 256 - message: "Interface has methods" +- name: NO_SUCH_PARAMLESS_CTOR + id: 125 + message: "No matching parameterless constructor" + +- name: NO_SUCH_PARAMLESS_CTOR_2 + id: 270 + message: "No Matching Parameterless Constructor, parameter count {}" -- name: ABSTRACT_METH_IN_ABSTRACT_CLASS - id: 257 - message: "Abstract class has abstract method {}" +- name: NO_SUCH_SIG_WITH_TRAILING_LAMBDA + id: 140 + message: "No matching call signature with trailing lambda" -- name: MISSING_ITERATOR_METHOD - id: 258 - message: "Object type doesn't have proper iterator method." +- name: NULLISH_CAST_TO_NONNULLISH + id: 304 + message: "Cannot cast 'null' or 'undefined' to non-nullish type." -- name: MISSING_ITERATOR_METHOD_WITH_SIG - id: 259 - message: "Cannot find iterator method with the required signature." +- name: OBJECT_LITERAL_METHOD_KEY + id: 74 + message: "Method '{}' cannot be used as a key of object literal." -- name: ITERATOR_MISSING_NEXT - id: 260 - message: "Iterator object doesn't have proper next method." +- name: OBJECT_LITERAL_NOT_KV + id: 64 + message: "The object literal properties must be key-value pairs" -- name: ITERATOR_DOESNT_RETURN_ITERABLE - id: 261 - message: "Iterator method must return an object which implements Iterator" +- name: OBJ_LIT_NOT_COVERING_UNION + id: 265 + message: "All variants of literals listed in the union type must be listed in the object literal" -- name: SWITCH_CASE_TYPE_INCOMPARABLE - id: 262 - message: "Switch case type '{}' is not comparable to discriminant type '{}'" +- name: OBJ_LIT_PROPERTY_REDECLARATION + id: 100 + message: "An object literal cannot have multiple properties with the same name." - name: OBJ_LIT_PROP_NAME_COLLISION id: 263 @@ -1049,521 +1102,491 @@ semantic: id: 264 message: "Object literal may only specify known properties" -- name: OBJ_LIT_NOT_COVERING_UNION - id: 265 - message: "All variants of literals listed in the union type must be listed in the object literal" +- name: OPERAND_NOT_NUMERIC + id: 66 + message: "Bad operand type, the type of the operand must be numeric type." -- name: PRECOND_FAILED - id: 266 - message: "Precondition check failed for {}" +- name: OP_NONNUMERIC + id: 107 + message: "Bad operand type, the types of the operands must be numeric type." -- name: POSTCOND_FAILED - id: 267 - message: "Postcondition check failed for {}" +- name: OVERLOADED_FUNCTION_REFERENCE + id: 229 + message: "Overloaded function identifier '{}' can not be used as value" -- name: INVISIBLE_INDEX_ACCESSOR - id: 268 - message: "Index access method is not visible here." +- name: OVERLOADED_MAIN + id: 373 + message: "Main overload is not enabled" -- name: EXTENSION_GETTER_INVALID_CTX - id: 269 - message: "Extension getter in wrong usage" +- name: OVERLOADED_METHOD_AS_VALUE + id: 307 + message: "Overloaded method is used as value" -- name: NO_SUCH_PARAMLESS_CTOR_2 - id: 270 - message: "No Matching Parameterless Constructor, parameter count {}" +- name: OVERLOADED_NAME_MUST_ALSO_EXPORTED + id: 390 + message: "Overload alias is exported, then overload functions must also be exported." -- name: INVISIBLE_ITERATOR - id: 272 - message: "Iterator method is not visible here." +- name: OVERLOADED_NAME_MUST_FUNCTION + id: 384 + message: "overloaded name must refer to an accessible method." -- name: RTYPE_PARAM_COUNT_MISMATCH - id: 273 - message: "Expected {} type arguments, got {} ." +- name: OVERLOADED_NAME_REFER_TO_OVERLOAD_FUNCTION + id: 389 + message: "The overloaded name '{}' can't refer to a function with overload signatures." -- name: EXPECTED_TYPE_ARGUMENTS - id: 274 - message: "Expected at least {} type arguments, but got {}." +- name: OVERLOADED_UNION_CALL + id: 391 + message: "Overload declaration cannot be called by union." -- name: INTERFACE_INSTANTIATION - id: 275 - message: "{} is an interface therefore cannot be instantiated." +- name: OVERLOAD_MODIFIERS_ABSTRACT + id: 392 + message: "overload declaration cannot contain abstract methods." -- name: KEYOF_REFERENCE_TYPE - id: 276 - message: "The `keyof` keyword can only be used for class or interface type." +- name: OVERLOAD_MUST_BOTH_CONSTRUCT + id: 388 + message: "The overload alias and the overloaded method must either both be constructors or both be non-constructors." -- name: FIXED_ARRAY_PARAM_ERROR - id: 277 - message: "FixedArray must have only one type parameter." +- name: OVERLOAD_NAME_MUST_BE_IDENTIFIER + id: 383 + message: "The name of overload declaration should be an identifier." -- name: LOCAL_CLASS_NATIVE_METHOD - id: 278 - message: "Local class '{}' shouldn't have native methods/constructors" +- name: OVERLOAD_SAME_ACCESS_MODIFIERS + id: 386 + message: "Overload alias and overloaded method name must have exactly the same modifiers (public, private, protected)." -- name: TUPLEN_NOT_IMPLEMENTED - id: 279 - message: "Tuple types with arity >16 are not yet implemented" +- name: OVERLOAD_SAME_ACCESS_MODIFIERS_STATIC_ASYNC + id: 387 + message: "Overload alias and overloaded method name must have exactly the same modifiers (static, async)." -- name: PROPERTY_MAYBE_MISSING_INIT - id: 280 - message: "Property '{}' might not have been initialized." +- name: OVERRIDE_DOESNT_OVERRIDE + id: 136 + message: "Method {}{} in {} not overriding any method" -- name: NOT_ALLOWED_THIS_IN_UNION_TYPE - id: 281 - message: "A 'this' cannot be used as a part of union type." +- name: PARAM_COUNT_MISMATCH + id: 124 + message: "Expected {} arguments, got {}." -- name: NOT_ALLOWED_THIS_IN_TUPLE_TYPE - id: 282 - message: "A 'this' cannot be used as a part of tuple type." +- name: POSSIBLY_NULLISH + id: 10 + message: "Value is possibly nullish." -- name: NOT_ALLOWED_THIS_IN_ARRAY_TYPE - id: 283 - message: "A 'this' cannot be used as type of array." +- name: POSTCOND_FAILED + id: 267 + message: "Postcondition check failed for {}" -- name: TYPE_FROM_UNION_TYPE_UNSUPPORTED - id: 284 - message: "Acquiring types for union types is not supported." +- name: PRECOND_FAILED + id: 266 + message: "Precondition check failed for {}" -- name: TYPE_FROM_UNRESOLVABLE_TYPE - id: 285 - message: "Unable to resolve type." +- name: PRIVATE_METHOD_AS_VALUE + id: 306 + message: "Private method is used as value" -- name: TYPE_FROM_TUPLE_TYPE_UNSUPPORTED - id: 286 - message: "Acquiring types for tuple types is not supported." +- name: PROPERTY_CAPTURE + id: 146 + message: "Property '{}' of enclosing class '{}' is not allowed to be captured from the local class '{}'" -- name: TYPE_FROM_STRING_LITERAL_TYPE_UNSUPPORTED - id: 287 - message: "Acquiring types for string literal types is not supported." +- name: PROPERTY_CAPTURE_IN_STATIC + id: 147 + message: "Not allowed to capture variable '{}' in static method" -- name: STATIC_REF_TO_NONSTATIC - id: 288 - message: "Cannot make a static reference to the non-static type {}" +- name: PROPERTY_MAYBE_MISSING_INIT + id: 280 + message: "Property '{}' might not have been initialized." -- name: EXPR_NOT_CALLABLE - id: 289 - message: "This expression is not callable." +- name: PROPERTY_NONEXISTENT + id: 87 + message: "Property '{}' does not exist on type '{}'" -- name: CALLEE_NONCONSTRUCTIBLE - id: 290 - message: "Type '{}' is not constructible." +- name: PROP_ACCESS_WITHOUT_THIS + id: 145 + message: "Property '{}' must be accessed through 'this'" -- name: NO_PARAMLESS_CTOR - id: 291 - message: "Type {} has no parameterless constructor. Initialization with literals is not supported if the type has no parameterless constructor. Declare the parameterless constructor explicitly or remove parametered constructors!" +- name: PROP_ASSIGN_TO_NUMERIC_INDEX + id: 324 + message: "Property '{}' of type '{}' is not assignable to numeric index type '{}'." -- name: EXPR_NONCONSTRUCTIBLE - id: 292 - message: "This expression is not constructible." +- name: PROP_ASSIGN_TO_STRING_INDEX + id: 327 + message: "Property '{}' of type '{}' is not assignable to string index type '{}'." + +- name: PROP_INCOMPAT + id: 319 + message: "Type '{}' is not compatible with type '{}' at property '{}'" - name: PROP_INVISIBLE id: 293 message: "Property {} is not visible here." -- name: CLASS_OR_IFACE_AS_OBJ - id: 294 - message: "Class or interface '{}' cannot be used as object" - -- name: NAMESPACE_CALL - id: 295 - message: "Namespace style identifier {} is not callable." - -- name: INSTANCEOF_NONOBJECT - id: 296 - message: "Using the 'instance of' operator with non-object type '{}'" - -- name: FIELD_REASSIGNMENT - id: 297 - message: "Cannot reassign {} {}" - -- name: FIELD_ASSIGN_TYPE_MISMATCH - id: 298 - message: "Cannot assign to a {} variable {}" - -- name: INVALID_TYPE_REF - id: 299 - message: "Invalid type reference." - -- name: UNION_NONCONSTRUCTIBLE - id: 300 - message: "The union type is not constructible." - -- name: UNRESOLVABLE_ARRAY - id: 301 - message: "Can't resolve array type" - -- name: IMPORT_ARG_NOT_STRING - id: 302 - message: "'import' expressions require string as argument." +- name: PROP_IS_STATIC + id: 207 + message: "'{}' is a static property of '{}'" -- name: AWAITED_NOT_PROMISE - id: 303 - message: "'await' expressions require Promise object as argument." +- name: PROP_NOT_STATIC + id: 208 + message: "'{}' is an instance property of '{}'" -- name: NULLISH_CAST_TO_NONNULLISH - id: 304 - message: "Cannot cast 'null' or 'undefined' to non-nullish type." +- name: READONLY_ARRAYLIKE_MODIFICATION + id: 58 + message: "Cannot modify an array or tuple content that has the readonly parameter" -- name: CAST_TO_NEVER - id: 305 - message: "Cast to 'never' is prohibited" +- name: READONLY_CALL + id: 27 + message: "Cannot call readonly type methods." -- name: PRIVATE_METHOD_AS_VALUE - id: 306 - message: "Private method is used as value" +- name: READONLY_FIELD_MULTIPLE_INIT + id: 210 + message: "Readonly field already initialized at declaration." -- name: OVERLOADED_METHOD_AS_VALUE - id: 307 - message: "Overloaded method is used as value" +- name: READONLY_PROPERTY_REASSIGN + id: 338 + message: "The 'Readonly' property cannot be reassigned." -- name: CIRCULAR_DEPENDENCY - id: 308 - message: "Circular dependency detected for identifier: {}" +- name: READ_FROM_WRITEONLY_PROP + id: 211 + message: "Cannot read from this property because it is writeonly." - name: RECURSIVE_CTOR id: 309 message: "Recursive constructor invocation" -- name: CYCLIC_INHERITANCE - id: 310 - message: "Cyclic inheritance involving {}." - -- name: CYCLIC_ALIAS - id: 311 - message: "Circular type alias reference" - - name: RECURSIVE_EXTENSION id: 312 message: "Type {} recursively references itself as a base type." -- name: CYCLIC_ALIAS_2 - id: 313 - message: "Type alias {} circularly refences itself" +- name: REDEFINITION + id: 349 + message: "{} '{}' is already defined." -- name: CYCLIC_VAR_REF - id: 314 - message: "'{}' is referenced directly or indirectly in its own initializer ot type annotation." +- name: REDEFINITION_DIFF_TYPE + id: 350 + message: "{} '{}' is already defined with different type." -- name: IFACE_MULTIPLE_EXTENSION - id: 315 - message: "Interface '{}' cannot simultaneously extend types '{}' and '{}'." +- name: REF_INVALID + id: 329 + message: "Invalid reference '{}'." -- name: DIFFERENT_SUBSEQ_DECL - id: 316 - message: "Subsequent variable declaration must have the same type. Variable '{}' must be of type '{}', but here has type '{}'." +- name: REPEATED_INTERFACE + id: 180 + message: "Repeated interface." -- name: DIFFERENT_SUBSEQ_PROP_DECL - id: 317 - message: "Subsequent variable declaration must have the same type. Variable '{}' must be of type '{}', but here has type '{}'." +- name: REQUIRED_PROP_MISSING_INIT + id: 226 + message: "Class property '{}' needs to be initialized for Required<{}>." -- name: INVALID_ASSIGNMNENT - id: 318 - message: "Type '{}' cannot be assigned to type '{}'" +- name: REST_PARAM_INCOMPAT_AT + id: 323 + message: "Type '{}' is not compatible with rest parameter type '{}' at index {}" -- name: PROP_INCOMPAT - id: 319 - message: "Type '{}' is not compatible with type '{}' at property '{}'" +- name: RETURN_DIFFERENT_PRIM + id: 150 + message: "Function cannot have different primitive return types, require '{}', found '{}'" -- name: IFACE_INVALID_EXTENDS - id: 320 - message: "Interface '{}' incorrectly extends interface '{}'" +- name: RETURN_ISNT_ITERATOR + id: 96 + message: "The return type of '{}' must be a type that implements Iterator interface." -- name: INVALID_ASSIGNMNENT_2 - id: 321 - message: "Type '{}' is not assignable to type '{}'." +- name: RETURN_THIS_OUTSIDE_METHOD + id: 31 + message: "Only extension function or a class method can return 'this'" -- name: DISJOINT_CONVERSION - id: 322 - message: "Conversion of type '{}' to type '{}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first." +- name: RETURN_TYPE_MISMATCH + id: 90 + message: "Return statement type is not compatible with the enclosing method's return type." -- name: REST_PARAM_INCOMPAT_AT - id: 323 - message: "Type '{}' is not compatible with rest parameter type '{}' at index {}" +- name: RETURN_WITHOUT_VALUE + id: 32 + message: "Missing return value." -- name: PROP_ASSIGN_TO_NUMERIC_INDEX - id: 324 - message: "Property '{}' of type '{}' is not assignable to numeric index type '{}'." +- name: RTYPE_PARAM_COUNT_MISMATCH + id: 273 + message: "Expected {} type arguments, got {} ." -- name: TUPLE_CONVERSION_FAILURE - id: 325 - message: "Tuple type couldn't be converted " +- name: SETTER_MISSING_IMPL + id: 189 + message: "{} is not abstract and does not implement setter for {} property in {}" -- name: INVALID_CAST - id: 326 - message: "Cannot cast type '{}' to '{}'" +- name: SETTER_NONVOID + id: 85 + message: "Setter must have void return type" -- name: PROP_ASSIGN_TO_STRING_INDEX - id: 327 - message: "Property '{}' of type '{}' is not assignable to string index type '{}'." +- name: SIG_INVISIBLE + id: 139 + message: "Signature {}{} is not visible here." -- name: UNIMPLEMENTED_REST_TUPLE - id: 328 - message: "Tuple types for rest arguments are not yet implemented" +- name: SIG_UNAVAILABLE + id: 137 + message: "Signature is not available here." -- name: REF_INVALID - id: 329 - message: "Invalid reference '{}'." +- name: SPREAD_OF_INVALID_TYPE + id: 49 + message: "Spread expression can be applied only to array or tuple type, but '{}' is provided" -- name: ID_WRONG_CTX - id: 330 - message: "Identifier '{}' is used in wrong context." +- name: SPREAD_ONTO_SINGLE_PARAM + id: 121 + message: "Spread argument cannot be passed for ordinary parameter." -- name: VARIANT_PARAM_INVARIAN_USE - id: 331 - message: "Type Parameter '{}' is declared as{} but occurs in 'invariant' position." +- name: STANDARD_ANNOTATION_REQUIRED + id: 6 + message: Only standard annotations are allowed to be applied on annotations. -- name: VARIANCE_TPARAM_IN_OUT - id: 332 - message: "Type Parameter '{}' is declared as 'in' but occurs in 'out' position." +- name: STATIC_INIT_IN_NESTED_CLASS + id: 14 + message: "Static initializer is not allowed in inner class." -- name: VARIANCE_TPARAM_OUT_IN - id: 333 - message: "Type Parameter '{}' is declared as 'out' but occurs in 'in' position." +- name: STATIC_METHOD_INVALID_MODIFIER + id: 77 + message: "Invalid method modifier(s): a static method can't have abstract, final or override modifier." -- name: SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST - id: 334 - message: "Enum switch case must be unqualified name of an enum constant" +- name: STATIC_METH_IN_CLASS_AND_INTERFACE + id: 221 + message: "Static {} method and static {} method both exist in class/interface {} is not allowed." + +- name: STATIC_PROP_INVALID_CTX + id: 173 + message: "Static property '{}' must be accessed through it's class '{}'" + +- name: STATIC_REF_TO_NONSTATIC + id: 288 + message: "Cannot make a static reference to the non-static type {}" - name: STATIC_UNION id: 335 message: "Static union member expression cannot be interpreted." -- name: CAST_FAIL_UNREACHABLE - id: 336 - message: "this cast should never fail" +- name: SUPER_NOT_ACCESSIBLE + id: 377 + message: "Class field '{}' defined by the parent class is not accessible in the child class via super." -- name: INTERFACE_PROPERTY_REQUIRES_SETTER - id: 337 - message: "Cannot implement interface {}: property '{}' must have a setter, but the implementation is readonly" +- name: SWITCH_CASE_DUPLICATE + id: 165 + message: "Case duplicate" -- name: READONLY_PROPERTY_REASSIGN - id: 338 - message: "The 'Readonly' property cannot be reassigned." +- name: SWITCH_CASE_INVALID_TYPE + id: 164 + message: "Unexpected type {}" -- name: ILLEGAL_NON_NULLISH_TYPE - id: 339 - message: "Only type parameters can be used as a nonnullish type" +- name: SWITCH_CASE_TYPE_INCOMPARABLE + id: 262 + message: "Switch case type '{}' is not comparable to discriminant type '{}'" -- name: ERROR_ARKTS_NO_LITERAL_INITIALIZATION_WITHOUT_PARAMETERLESS_CONSTRUCTOR - id: 340 - message: "Initialization with literals is not supported if the type has no parameterless constructor. Declare the parameterless constructor explicitly or remove parametered constructors!" +- name: SWITCH_CASE_VAR_DUPLICATE_VAL + id: 166 + message: "Variable has same value with another switch case" -- name: ERROR_ARKTS_NO_DECLARATION_MERGING - id: 341 - message: "Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase!" +- name: SWITCH_ENUM_NOT_UNQUALIFIED_ENUM_CONST + id: 334 + message: "Enum switch case must be unqualified name of an enum constant" -- name: ERROR_ARKTS_NO_ENUM_MIXED_TYPES - id: 342 - message: "Enumeration members can be initialized only by compile-time expressions and initializers must be of the same type." +- name: TEMPLATE_COUNT_MISMATCH + id: 28 + message: "Invalid string template expression" -- name: ERROR_ARKTS_NO_PROPERTIES_BY_INDEX - id: 343 - message: "Indexed signatures are not allowed. Use arrays instead!" +- name: TEMPORAL_DEADZONE + id: 365 + message: "Variable '{}' is accessed before it's initialization." -- name: CONSTANT_FLOATING_POINT_COVERSION - id: 344 - message: "Floating-point value cannot be converted" +- name: THIS_OR_SUPER_IN_CTOR + id: 235 + message: "Using {} is not allowed in constructor" -- name: CONSTANT_VALUE_OUT_OF_RANGE - id: 345 - message: "Value is out of range" +- name: THIS_OUTSIDE_METHOD_CTX + id: 138 + message: "Cannot reference 'this' in this context." -- name: WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION - id: 346 - message: "Wrong type of operands for binary expression" +- name: TUPLEN_NOT_IMPLEMENTED + id: 279 + message: "Tuple types with arity >16 are not yet implemented" -- name: WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION - id: 347 - message: "Wrong operand type for unary expression" +- name: TUPLE_CONVERSION_FAILURE + id: 325 + message: "Tuple type couldn't be converted " + +- name: TUPLE_INDEX_NONCONST + id: 199 + message: "Only constant expression allowed for element access on tuples." + +- name: TUPLE_INDEX_NOT_INT + id: 200 + message: "Only integer type allowed for element access on tuples." + +- name: TUPLE_INDEX_OOB + id: 198 + message: "Element accessor value is out of tuple size bounds." + +- name: TUPLE_SIZE_MISMATCH + id: 56 + message: "Too many elements in array initializer for tuple with size of {}" + +- name: TUPLE_UNASSIGNABLE_ARRAY + id: 57 + message: "Array initializer's type is not assignable to tuple type at index: {}" + +- name: TUPLE_WRONG_NUMBER_OF_ELEMS + id: 231 + message: "Initializer has {} elements, but tuple requires {}" -- name: UNION_METHOD_SIGNATURE - id: 348 - message: "Union constituent types should have only one common method signature." +- name: TYPEARG_TYPEPARAM_SUBTYPING + id: 228 + message: "Type argument '{}' should be a subtype of '{}'-constraint" -- name: REDEFINITION - id: 349 - message: "{} '{}' is already defined." +- name: TYPE_FROM_STRING_LITERAL_TYPE_UNSUPPORTED + id: 287 + message: "Acquiring types for string literal types is not supported." -- name: REDEFINITION_DIFF_TYPE - id: 350 - message: "{} '{}' is already defined with different type." +- name: TYPE_FROM_TUPLE_TYPE_UNSUPPORTED + id: 286 + message: "Acquiring types for tuple types is not supported." -- name: VARIABLE_REDECLARED - id: 351 - message: "Variable '{}' has already been declared." +- name: TYPE_FROM_UNION_TYPE_UNSUPPORTED + id: 284 + message: "Acquiring types for union types is not supported." -- name: DEFAULT_DYNAMIC_IMPORT - id: 352 - message: "Default import is currently not implemented in dynamic import" +- name: TYPE_FROM_UNRESOLVABLE_TYPE + id: 285 + message: "Unable to resolve type." -- name: DEFAULT_EXPORT_DIRECT_IMPORTED - id: 353 - message: "Use the default import syntax to import a default exported element" +- name: TYPE_MISMATCH_AT_IDX + id: 46 + message: "Type '{}' is not compatible with type '{}' at index {}" -- name: IMPORTING_NONEXPORTED_TYPE - id: 354 - message: "Cannot import '{}', imported type imports only exported types." +- name: TYPE_MISMATCH_ENUM + id: 152 + message: "Cannot assign type '{}' for variable {}." -- name: IMPORTED_NOT_EXPORTED - id: 355 - message: "Imported element not exported '{}'" +- name: TYPE_NOT_FOUND + id: 371 + message: "Cannot find type '{}'." -- name: IMPORT_NOT_FOUND - id: 356 - message: "Cannot find imported element '{}'" +- name: TYPE_PARAMETER_AS_ARRAY_ELEMENT_TYPE + id: 7 + message: Cannot use array creation expression with type parameter. -- name: IMPORT_RENAMES_ANNOTATION - id: 357 - message: "Can not rename annotation '{}' in export or import statements." +- name: TYPE_PARAM_CIRCULAR_CONSTRAINT + id: 184 + message: "Type parameter '{}' has circular constraint dependency." -- name: DEFAULT_IMPORT_NOT_FOUND - id: 358 - message: "Cannot find default imported element in the target" +- name: TYPE_PARAM_USE_BEFORE_DEFINE + id: 183 + message: "Type Parameter {} should be defined before use." -- name: MODULE_INDEX_MISSING - id: 359 - message: "Cannot find index.[ets|ts] or package module in folder: {}" +- name: UNCALLABLE_TYPE + id: 60 + message: "Type '{}' has no call signatures." -- name: IMPORT_NOT_FOUND_2 - id: 360 - message: "Cannot find import: {}" +- name: UNDEFINED_METHOD + id: 212 + message: "Method {} does not exist on this type." -- name: EXPORT_INCORRECT - id: 361 - message: "Incorrect export '{}'" +- name: UNDEFINED_PROPERTY + id: 65 + message: "type {} has no property named {}" -- name: AMBIGUOUS_EXPORT - id: 362 - message: "Ambiguous export '{}'" +- name: UNEXPECTED_ARRAY + id: 72 + message: "Expected type for array literal should be an array type, got {}" -- name: CONST_WITHOUT_INIT - id: 363 - message: "Missing initializer in const declaration" +- name: UNEXPECTED_FUNC_BODY + id: 83 + message: "Native, Abstract and Declare methods cannot have body." + +- name: UNEXPECTED_NONVOID + id: 94 + message: "'{}' should have void return type." - name: UNEXPECTED_STRUCT id: 364 message: "Structs are only used to define UI components, it should be translated at 'plugin after parser' phase." -- name: TEMPORAL_DEADZONE - id: 365 - message: "Variable '{}' is accessed before it's initialization." - -- name: INVALID_CAPTURE - id: 366 - message: "Cannot capture variable '{}'." +- name: UNEXPECTED_VALUE_RETURN + id: 89 + message: "Unexpected return value, enclosing method return type is void." -- name: INVALID_EXPORT - id: 367 - message: "Invalid exported binding" +- name: UNEXPECTED_VOID + id: 93 + message: "'{}' shouldn't have void return type." -- name: NOT_IMPLEMENTED - id: 368 - message: "not implemented" +- name: UNIMPLEMENTED_REST_TUPLE + id: 328 + message: "Tuple types for rest arguments are not yet implemented" -- name: ID_REDECLARED - id: 369 - message: "Identifier '{}' has already been declared." +- name: UNION_MEMBER_ILLEGAL_TYPE + id: 245 + message: "Type {} is illegal in union member expression." -- name: MERGED_DECLS - id: 370 - message: "Merging declarations is not supported, please keep all definitions of classes, interfaces and enums compact in the codebase!" +- name: UNION_METHOD_SIGNATURE + id: 348 + message: "Union constituent types should have only one common method signature." -- name: TYPE_NOT_FOUND - id: 371 - message: "Cannot find type '{}'." +- name: UNION_NONCONSTRUCTIBLE + id: 300 + message: "The union type is not constructible." -- name: INTERFACE_REDECLARED - id: 372 - message: "Interface redeclaration is not allowed" +- name: UNRESOLVABLE_ARRAY + id: 301 + message: "Can't resolve array type" -- name: OVERLOADED_MAIN - id: 373 - message: "Main overload is not enabled" +- name: UNRESOLVED_REF + id: 143 + message: "Unresolved reference {}" -- name: MULTIPLE_DEFAULT_EXPORTS - id: 374 - message: "Only one default export is allowed in a module" +- name: UNSUPPORTED_CLASS_LITERAL + id: 20 + message: "Class literal is not yet supported." - name: USE_BEFORE_INIT id: 375 message: "{} '{}' is used before being assigned." -- name: LATE_INITIALIZATION_FIELD_HAS_INVALID_TYPE - id: 376 - message: "Late-initialized field cannot be nullish types or possibly nullish types." - -- name: SUPER_NOT_ACCESSIBLE - id: 377 - message: "Class field '{}' defined by the parent class is not accessible in the child class via super." - -- name: INTERFACE_EXTENDS_CLASS - id: 378 - message: "Interfaces cannot extend classes, only other interfaces." -- name: CYCLIC_TYPE_OF - id: 379 - message: "Circular type of reference" - -- name: CYCLIC_CLASS_SUPER_TYPE - id: 380 - message: "Class's super type is itself" - -- name: CYCLIC_CALLEE - id: 381 - message: "Circular call function" - -- name: DYMANIC_INIT_WITH_OBJEXPR - id: 382 - message: "Dymanic Type {} cannot be initialize with an object expression" - -- name: OVERLOAD_NAME_MUST_BE_IDENTIFIER - id: 383 - message: "The name of overload declaration should be an identifier." +- name: UTILITY_TYPE_UNIMPLEMENTED + id: 225 + message: "This utility type is not yet implemented." -- name: OVERLOADED_NAME_MUST_FUNCTION - id: 384 - message: "overloaded name must refer to an accessible method." +- name: UTIL_TYPE_INVALID_TYPE_PARAM_COUNT + id: 223 + message: "Invalid number of type parameters for {} type, should be 1." -- name: DUPLICATE_OVERLOADED_NAME - id: 385 - message: "Duplicate overloaded method." +- name: UTIL_TYPE_OF_NONREFERENCE + id: 224 + message: "Only reference types can be converted to utility types." -- name: OVERLOAD_SAME_ACCESS_MODIFIERS - id: 386 - message: "Overload alias and overloaded method name must have exactly the same modifiers (public, private, protected)." +- name: VARIABLE_REDECLARED + id: 351 + message: "Variable '{}' has already been declared." -- name: OVERLOAD_SAME_ACCESS_MODIFIERS_STATIC_ASYNC - id: 387 - message: "Overload alias and overloaded method name must have exactly the same modifiers (static, async)." +- name: VARIANCE_TPARAM_IN_OUT + id: 332 + message: "Type Parameter '{}' is declared as 'in' but occurs in 'out' position." -- name: OVERLOAD_MUST_BOTH_CONSTRUCT - id: 388 - message: "The overload alias and the overloaded method must either both be constructors or both be non-constructors." +- name: VARIANCE_TPARAM_OUT_IN + id: 333 + message: "Type Parameter '{}' is declared as 'out' but occurs in 'in' position." -- name: OVERLOADED_NAME_REFER_TO_OVERLOAD_FUNCTION - id: 389 - message: "The overloaded name '{}' can't refer to a function with overload signatures." +- name: VARIANT_PARAM_INVARIAN_USE + id: 331 + message: "Type Parameter '{}' is declared as{} but occurs in 'invariant' position." -- name: OVERLOADED_NAME_MUST_ALSO_EXPORTED - id: 390 - message: "Overload alias is exported, then overload functions must also be exported." +- name: VOID_IN_LOGIC + id: 9 + message: "An expression of type 'void' cannot be tested for truthiness" -- name: OVERLOADED_UNION_CALL - id: 391 - message: "Overload declaration cannot be called by union." +- name: VOID_VALUE + id: 78 + message: "Cannot use type 'void' as value. " -- name: OVERLOAD_MODIFIERS_ABSTRACT - id: 392 - message: "overload declaration cannot contain abstract methods." - -- name: INVALID_RECORD_PROPERTY - id: 393 - message: "Invalid record property" +- name: WRONG_OPERAND_TYPE_FOR_BINARY_EXPRESSION + id: 346 + message: "Wrong type of operands for binary expression" -- name: METHOD_ASSIGNMENT - id: 394 - message: "Class methods cannot be overwritten." +- name: WRONG_OPERAND_TYPE_FOR_UNARY_EXPRESSION + id: 347 + message: "Wrong operand type for unary expression" -- name: INVALID_LAMBDA_PARAMETER - id: 395 - message: "Invalid lambda parameter. Expected: 'identifier(: type)?', 'identifier?(: type)?' or '...identifier(: type)?'." +graveyard: +- 8 +- 29 +- 167 +- 233 +- 234 +- 271 +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 87fa64579b..47d782ae57 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -12,1306 +12,1316 @@ # limitations under the License. syntax: -- name: MISSING_TYPE_ANNOTATION - id: 1 - message: "Missing type annotation for property '{}'." -- name: DIFFERENT_PACKAGE_NAME - id: 2 - message: "Files '{}' and '{}' are in the same folder, but have different package names." +- name: ABSTRACT_METHODS_ONLY_IN_ABSTRACT_CLASS + id: 184 + message: "Abstract methods can only appear within an abstract class." -- name: PACKAGE_MODULE_IMPORT_OWN_PACKAGE - id: 3 - message: "Package module cannot import from a file in it's own package." +- name: ABSTRACT_METHOD_ASYNC + id: 118 + message: "Abstract method cannot be async." + +- name: ACCESS_BEFORE_FIELD_METHOD + id: 120 + message: "Access modifier must precede field and method modifiers." + +- name: ALREADY_EXPORTED + id: 282 + message: "Cannot export '{}', it was already exported." - name: AMBIENT_CLASS_MISSING_BODY id: 4 message: "Ambient class declarations must have a body." -- name: EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER - id: 5 - message: "export default is not allowed to export multiple specifiers." - -- name: NAMESPACE_MERGE_ERROR - id: 6 - message: "Unable to merge namespaces '{}', because their modifiers are different." +- name: ANNOTATION_ABSTRACT + id: 29 + message: "Annotations are not allowed on an abstract class or methods." -- name: NAMESPACE_ANNOTATION_CONFLICT - id: 7 - message: "Annotation conflict! Multiple namespace declarations for '{}' cannot each have annotations." +- name: ANNOTATION_DECLARATION_ACCESS_MODIFIER + id: 210 + message: "Annotation declaration can not have access modifier." -- name: INVALID_NODE_NUMBER - id: 8 - message: "Invalid node number in format expression." +- name: ANNOTATION_METHOD_AS_PROP + id: 25 + message: "Annotation can not have method as property." -- name: INVALID_NODE_TYPE - id: 9 - message: "Invalid node type in format expression." +- name: ANNOTATION_NOT_ALLOWED + id: 113 + message: "Annotations cannot be applied here." -- name: INSERT_NODE_ABSENT - id: 10 - message: "There is no any node to insert at the placeholder position." +- name: ANNOTATION_ONLY_TOP_LEVEL + id: 114 + message: "Annotations can only be declared at the top level." -- name: INVALID_INSERT_NODE - id: 11 - message: "Inserting node type differs from that required by format specification." +- name: ANNOTATION_PROPERTY_ACCESS_MODIFIERS + id: 24 + message: "Annotation property can not have access modifiers." -- name: INVALID_CLASS_FIELD - id: 12 - message: "Cannot parse class field definition property." +- name: ANNOTATION_WRONG_DEC + id: 28 + message: "Annotations are not allowed on this type of declaration." -- name: INVALID_CLASS_METHOD - id: 13 - message: "Cannot parse class method definition property." +- name: ASSIGN_TO_ARGS_INVALID + id: 57 + message: "Assigning to 'arguments' in strict mode is invalid." -- name: REQUIRED_PARAM_AFTER_DEFAULT - id: 14 - message: "Required parameter follows default parameter(s)." +- name: ASSIGN_TO_EVAL_INVALID + id: 51 + message: "Assigning to 'eval' in strict mode is invalid." -- name: REST_AND_DEFAULT_SAME_TIME - id: 15 - message: "Both optional and rest parameters are not allowed in function's parameter list." +- name: ASTERIKS_NOT_ALLOWED_IN_SELECTIVE_BINDING + id: 102 + message: "The '*' token is not allowed as a selective binding (between braces)." -- name: UNEXPECTED_TOKEN - id: 16 - message: "Unexpected token." +- name: ASYNC_CONSTRUCTOR + id: 200 + message: "Constructor should not be async." -- name: INDEX_TYPE_EXPECTED - id: 17 - message: "Index type expected in index signature." +- name: ASYNC_FLAG_ONLY_FOR_TOP_FUN + id: 202 + message: "'async' flags must be used for functions only at top-level." -- name: INDEX_TYPE_NOT_NUMBER - id: 18 - message: "Index type must be number in index signature." +- name: ASYNC_IN_AMBIENT_CONTEXT + id: 106 + message: "The modifier async cannot be used in an ambient context." -- name: EXPECTED_BRACKETS_IN_INDEX - id: 19 - message: "] expected in index signature." +- name: ASYNC_METHOD_LINE_TERM + id: 197 + message: "Async methods cannot have a line terminator between 'async' and the property name." -- name: INDEX_MISSING_TYPE - id: 20 - message: "An index signature must have a type annotation." +- name: AS_CONST_USAGE + id: 311 + message: "'as const' assertion is not supported." -- name: INDEX_MISSING_IDENTIFIER - id: 21 - message: "Return type of index signature from exported class or interface need to be identifier." +- name: AWAIT_IN_ARROW_FUN_PARAM + id: 46 + message: "await is not allowed in arrow function parameters." -- name: EXTENSION_GETTER_WRONG_PARAM - id: 22 - message: "Extension Getter can only have 1 parameter." +- name: AWAIT_RESERVED_IDENTIFIER_IN_MODULE + id: 213 + message: "'await' is a reserved identifier in module code." -- name: EXTENSION_SETTER_WRONG_PARAM - id: 23 - message: "Extension Setter can only have 2 parameters." +- name: BINDING_ARGS_INVALID + id: 182 + message: "Binding 'arguments' in strict mode is invalid." -- name: ANNOTATION_PROPERTY_ACCESS_MODIFIERS - id: 24 - message: "Annotation property can not have access modifiers." +- name: BINDING_EVAL_INVALID + id: 190 + message: "Binding 'eval' in strict mode is invalid." -- name: ANNOTATION_METHOD_AS_PROP - id: 25 - message: "Annotation can not have method as property." +- name: BINDING_PATTERN_PARAM_CANNOT_BE_OPTIONAL + id: 217 + message: "A binding pattern parameter cannot be optional in an implementation signature." -- name: INVALID_ARGUMENT_PASSED - id: 26 - message: "Invalid argument passed to '{}'." +- name: CANNOT_EXPORT_SAME_TYPE_TWICE + id: 284 + message: "Cannot export the same '{}' type twice." -- name: INVALID_VAL_ANNOTATION_FIELD - id: 27 - message: "Invalid value for annotation field, expected a constant literal." +- name: CAN_NOT_FIND_NAME_TO_EXPORT + id: 279 + message: "Cannot find name '{}' to export." -- name: ANNOTATION_WRONG_DEC - id: 28 - message: "Annotations are not allowed on this type of declaration." +- name: CAN_NOT_RENAME_ANNOTATION + id: 280 + message: "Can not rename annotation '{}' in export or import statements." -- name: ANNOTATION_ABSTRACT - id: 29 - message: "Annotations are not allowed on an abstract class or methods." +- name: CATCH_CLAUSE_VAR_HAS_INIT + id: 101 + message: "Catch clause variable cannot have an initializer." -- name: LOCAL_CLASS_ACCESS_MOD - id: 30 - message: "Local class or interface declaration members can not have access modifies." +- name: CLASS_FIELD_CONSTRUCTOR + id: 144 + message: "Classes may not have a field named 'constructor'." -- name: GETTER_SETTER_NOT_ABSTRACT - id: 31 - message: "Getter and setter methods must be abstracts in the interface body." +- name: CLASS_INTERFACE_METHOD_OVERLOADED_NAME_MUST_IDENT + id: 324 + message: "The overloaded method name in class/interface method overload declaration must be identifier." -- name: PRIVATE_INTERFACE_MISSING_BODY - id: 32 - message: "Private interface methods must have body." +- name: CLASS_OUT_OF_ORDER + id: 80 + message: "Class range out of order." -- name: READONLY_INTERFACE_METHOD - id: 33 - message: "Modifier 'readonly' cannot be applied to an interface method." +- name: CONFLICTING_FIELD_MODIFIERS + id: 127 + message: "Conflicting modifiers '!' and '?' on field." -- name: MULTIPLE_STATIC_BLOCK - id: 34 - message: "Only one static block is allowed in one namespace or class." +- name: CONSTANT_MULTI_INITIALIZED_IN_STATIC_BLOCK + id: 290 + message: "package constant property initialization can only be applied once in static block" -- name: INVALID_ENUM_TYPE - id: 35 - message: "Invalid enum initialization type." +- name: DECALRE_IN_AMBIENT_CONTEXT + id: 104 + message: "A 'declare' modifier cannot be used in an already ambient context." -- name: ENUM_INVALID_INIT - id: 36 - message: "Invalid enum initialization value" +- name: DECLARE_MODIFIER_ON_INVALID_CLASS_ELEMENT + id: 157 + message: "'declare modifier cannot appear on class elements of this kind." -- name: ONLY_CALL_AFTER_LAUNCH - id: 37 - message: "Only call expressions are allowed after 'launch'." +- name: DECORATORS_INVALID + id: 183 + message: "Decorators are not valid here." -- name: MISSING_LOOP_AFTER_LABEL - id: 38 - message: "Label must be followed by a loop statement." +- name: DEEP_NESTING + id: 305 + message: "Maximum allowed nesting level exceeded." -- name: MISSING_CATCH_OR_FINALLY_AFTER_TRY - id: 39 - message: "A try statement should contain either finally clause or at least one catch clause." +- name: DEFAULT_ONLY_FOR_OPTIONAL + id: 133 + message: "Default value is allowed only for optional parameters." -- name: ILLEGAL_START_STRUCT_CLASS - id: 40 - message: "Illegal start of {} expression." +- name: DEFAULT_UNDEF_NOT_ALLOWED + id: 132 + message: "Not enable default value with default undefined." -- name: ONLY_EXPORT_CLASS_OR_INTERFACE - id: 41 - message: "Can only type export class or interface." +- name: DELETING_LOCAL_VAR + id: 50 + message: "Deleting local variable in strict mode." -- name: INVALID_EXPORT_DEFAULT - id: 42 - message: "Can not export annotation default." +- name: DELETING_PRIVATE_FIELDS + id: 70 + message: "Private fields can not be deleted." -- name: EXPORT_NON_DECLARATION - id: 43 - message: "Export is allowed only for declarations." +- name: DIFFERENT_PACKAGE_NAME + id: 2 + message: "Files '{}' and '{}' are in the same folder, but have different package names." -- name: THIS_IN_NON_STATIC_METHOD - id: 44 - message: "A 'this' type is available only as return type in a non-static method of a class or struct and extension functions." +- name: DIVISION_BY_ZERO + id: 273 + message: "Division by zero is not allowed." -- name: UNEXPECTED_ID - id: 45 - message: "Unexpected identifier." +- name: DUPLICATED_IDENTIFIER + id: 215 + message: "Duplicated identifier." -- name: AWAIT_IN_ARROW_FUN_PARAM - id: 46 - message: "await is not allowed in arrow function parameters." +- name: DUPLICATED_MODIFIER + id: 115 + message: "Duplicated modifier is not allowed." -- name: UNEXPECTED_PRIVATE - id: 47 - message: "Unexpected private identifier." +- name: DUPLICATE_EXPORT_NAME + id: 281 + message: "The given name '{}' is already used in another export." -- name: IMPORT_META_DIRECT_EVAL - id: 48 - message: "'import.Meta' is not allowed in direct eval in module code." +- name: DUPLICATE_GROUP_NAME + id: 82 + message: "Duplicate group name." -- name: INVALID_DESTRUCTURING_TARGET - id: 49 - message: "Invalid destructuring assignment target." +- name: DUPLICATE_PROTO_FIELDS + id: 285 + message: "Duplicate __proto__ fields are not allowed in object literals" -- name: DELETING_LOCAL_VAR - id: 50 - message: "Deleting local variable in strict mode." +- name: ENUM_INVALID_INIT + id: 36 + message: "Invalid enum initialization value" -- name: ASSIGN_TO_EVAL_INVALID - id: 51 - message: "Assigning to 'eval' in strict mode is invalid." +- name: ENUM_OR_ANNOTATION_DIVIDE_BY_ZERO + id: 293 + message: "Division by zero are not allowed in Enum or Annotation" -- name: EXPECTED_EXPRESSION_GOT_ARROW - id: 52 - message: "Expected expression, got '=>'." +- name: ENUM_STRING_TYPE_ALL_ITEMS_INIT + id: 276 + message: "All items of string-type enumeration should be explicitly initialized." -- name: INVALID_LEFT_SITE_OPERATOR - id: 53 - message: "Invalid left-hand side operator." +- name: ERROR_ARKTS_NO_AMBIENT_DECLS + id: 308 + message: "Ambient module declaration is not supported!" -- name: YIELD_IN_GENERATOR_PARAM - id: 54 - message: "Yield is not allowed in generator parameters." +- name: ERROR_ARKTS_NO_DEBUGGER_STATEMENT + id: 299 + message: "Debugger statement is not supported!" -- name: INVALID_REST_ELEMENT - id: 55 - message: "Invalid rest element." +- name: ERROR_ARKTS_NO_EXPORT_ASSIGNMENT + id: 307 + message: "'export = ...' syntax is not supported, use regular import/export instead!" -- name: TAGGED_TEMPLATE_LITERALS_IN_OPTIONALCHAIN - id: 56 - message: "Tagged Template Literals are not allowed in optionalChain." +- name: ERROR_ARKTS_NO_IMPORT_ASSERTIONS + id: 313 + message: "Import assertion is not supported, please use the ordinary import syntax instead!" -- name: ASSIGN_TO_ARGS_INVALID - id: 57 - message: "Assigning to 'arguments' in strict mode is invalid." +- name: ERROR_ARKTS_NO_PRIVATE_IDENTIFIERS + id: 298 + message: "Use 'private' keyword to declare an identifier as private." -- name: GETTER_FORMAL_PARAMS - id: 58 - message: "Getter must not have formal parameters." +- name: ERROR_ARKTS_NO_REQUIRE + id: 312 + message: "Importing by 'require' and 'import' assignment is not supported, use 'import * as ... from ...' form instead!" -- name: NULLISH_COALESCING_MISSING_PARENS - id: 59 - message: "Nullish coalescing operator ?? requires parens when mixing with logical operators." +- name: ERROR_ARKTS_NO_VAR + id: 297 + message: "'var' keyword is not supported. Use 'let' instead." -- name: NEW_WITH_IMPORT - id: 60 - message: "Cannot use new with import(...)." +- name: ESCAPE_SEQUENCES_IN_AS + id: 108 + message: "Escape sequences are not allowed in 'as' keyword." -- name: UNEXPECTED_SUPER - id: 61 - message: "Unexpected super keyword." +- name: ESCAPE_SEQUENCES_IN_KEYWORD + id: 271 + message: "Escape sequences are not allowed in keyword." -- name: OBJECT_PATTER_CONTAIN_METHODS - id: 62 - message: "Object pattern can't contain methods." +- name: EVAL_OR_ARGUMENTS_IN_STRICT_MODE + id: 207 + message: "'eval' or 'arguments' can't be defined or assigned to in strict mode code." -- name: SETTER_FORMAL_PARAMS - id: 63 - message: "Setter must have exactly one formal parameter." +- name: EXPECTED_ARROW_SAME_LINE + id: 195 + message: "expected '=>' on the same line after an argument list, got line terminator." -- name: INSUFFICIENT_PARAM_IN_ARROW_FUN - id: 64 - message: "Insufficient formal parameter in arrow function." +- name: EXPECTED_BRACKETS_IN_INDEX + id: 19 + message: "] expected in index signature." -- name: ILLEGAL_AWAIT_IN_ASYNC_FUN - id: 65 - message: "Illegal await-expression in formal parameters of async function." +- name: EXPECTED_EXPRESSION_GOT_ARROW + id: 52 + message: "Expected expression, got '=>'." -- name: YIELD_IN_ARROW_FUN_PARAM - id: 66 - message: "yield is not allowed in arrow function parameters." +- name: EXPECTED_PARAM_GOT_PARAM + id: 230 + message: "Expected '{}', got '{}'." -- name: REST_PARAM_NOT_LAST - id: 67 - message: "Rest parameter must be the last formal parameter." +- name: EXPLICIT_PARAM_TYPE + id: 194 + message: "Parameter declaration should have an explicit type annotation." -- name: META_PROP_FOR_IMPORT - id: 68 - message: "The only valid meta property for import is import.Meta." +- name: EXPORT_DEFAULT_NO_REEXPORT + id: 244 + message: "Cannot use 'export default' in re-export context" -- name: IMPORT_META_ONLY_MODULE - id: 69 - message: "'import.Meta' may appear only with 'sourceType: module'." +- name: EXPORT_DEFAULT_WITH_MUPLTIPLE_SPECIFIER + id: 5 + message: "export default is not allowed to export multiple specifiers." -- name: DELETING_PRIVATE_FIELDS - id: 70 - message: "Private fields can not be deleted." +- name: EXPORT_IN_NAMESPACE + id: 111 + message: "Export declarations are not permitted in a namespace." -- name: INVALID_LEFT_IN_PREFIX - id: 71 - message: "Invalid left-hand side in prefix operation." +- name: EXPORT_NON_DECLARATION + id: 43 + message: "Export is allowed only for declarations." -- name: INVALID_LEFT_SIDE_IN_ASSIGNMENT - id: 72 - message: "Invalid left-hand side in assignment expression." +- name: EXPORT_WITHOUT_DECLARE_IN_DECL_MODULE + id: 296 + message: "Export keyword without declare shouldn't be used in declaration module." -- name: NEW_TARGET_IS_NOT_ALLOWED - id: 73 - message: "'new.Target' is not allowed here." +- name: EXTENSION_ACCESSOR_RECEIVER + id: 146 + message: "Extension Accessor must have a receiver." -- name: NEW_TARGET_WITH_ESCAPED_CHARS - id: 74 - message: "'new.Target' must not contain escaped characters." +- name: EXTENSION_GETTER_WRONG_PARAM + id: 22 + message: "Extension Getter can only have 1 parameter." -- name: INVALID_CLOSING_PARENTHESIS - id: 75 - message: "Invalid closing parenthesis." +- name: EXTENSION_SETTER_WRONG_PARAM + id: 23 + message: "Extension Setter can only have 2 parameters." -- name: INVALID_CAPTURING_GROUP - id: 76 - message: "Invalid capturing group." +- name: FIELD_IN_PARAM + id: 319 + message: "Declaring fields in parameter list is not supported" -- name: INVALID_CHAR - id: 77 - message: "Invalid character." +- name: FIELD_TPYE_ANNOTATION_MISSING + id: 121 + message: "Field type annotation expected." -- name: QUANTIFIER_OUT_OF_ORDER - id: 78 - message: "Quantifier range out of order." +- name: FOR_AWAIT_OF_VAR_NOT_INIT + id: 97 + message: "for-await-of loop variable declaration may not have an initializer." -- name: INVALIDE_CHAR_CLASS - id: 79 - message: "Invalid character class." +- name: FOR_IN_LOOP_HAS_INIT + id: 164 + message: "for-in loop variable declaration may not have an initializer." -- name: CLASS_OUT_OF_ORDER - id: 80 - message: "Class range out of order." +- name: FOR_OF_LOOP_HAS_INIT + id: 168 + message: "for-of loop variable declaration may not have an initializer." -- name: INVALID_DECIMAL_ESCAPE - id: 81 - message: "Invalid decimal escape." +- name: FUNCTION_OVERLOADED_NAME_MUST_QUALIFIED_NAME + id: 325 + message: "The overloaded method name in function overload declaration must be qualified name." -- name: DUPLICATE_GROUP_NAME - id: 82 - message: "Duplicate group name." +- name: FUNC_EXPR + id: 320 + message: "Function expressions are not supported, use arrow functions instead" -- name: INVALID_HEX_ESCAPE - id: 83 - message: "Invalid hex escape." +- name: FUNC_PARAM_THIS_FIRST + id: 158 + message: "Function Parameter 'this' must be the first." -- name: INVALID_GROUP_NAME - id: 84 - message: "Invalid group name." +- name: FUN_PARAM_THIS_MISSING_TYPE + id: 99 + message: "The function parameter 'this' must explicitly specify the typeAnnotation." -- name: INVALID_GROUP - id: 85 - message: "Invalid group." +- name: GENERATORS_ONLY_TOP_LEVEL_OR_INSIDE_BLOCK + id: 173 + message: "Generators can only be declared at the top level or inside a block." -- name: UNTERMINATED_UNICODE_PROP_ESCAPE - id: 86 - message: "Unterminated Unicode property escape." +- name: GENERATOR_FUNCTION + id: 314 + message: "Generator functions are not supported, please use async/await mechanism for multitasking" -- name: INVALID_ESCAPE - id: 87 - message: "Invalid escape." +- name: GETTER_FORMAL_PARAMS + id: 58 + message: "Getter must not have formal parameters." -- name: INVALID_QUANTIFIER - id: 88 - message: "Invalid quantifier, nothing to repeat." +- name: GETTER_SETTER_NOT_ABSTRACT + id: 31 + message: "Getter and setter methods must be abstracts in the interface body." -- name: INVALID_NAME_BACKREFERENCE - id: 89 - message: "Invalid named backreference." +- name: GET_ACCESSOR_MUST_BE_AT_LEAST_AS_ACCESSIBLE + id: 205 + message: "A get accessor must be at least as accessible as the setter." -- name: INVALID_NON_CAPTURING_GROUP - id: 90 - message: "Invalid non-capturing group." +- name: HARD_KEYWORD_IDENT + id: 316 + message: "Hard keyword '{}' cannot be used as identifier" -- name: INVALID_UNICODE_ESCAPE - id: 91 - message: "Invalid Unicode escape." +- name: HEXADECIMAL_EXPECTED + id: 248 + message: "Hexadecimal digit expected." -- name: INVALID_CONTROL_ESCAPE - id: 92 - message: "Invalid control escape." +- name: IDENTIFIER_EXPECTED + id: 131 + message: "Identifier is needed here." -- name: INVALID_ASSERT - id: 93 - message: "Invalid assertion." +- name: IDENTIFIER_EXPECTED_HERE + id: 224 + message: "Identifier expected, got '{}'." -- name: INVALID_UNICODE_PROP_ESCAPE - id: 94 - message: "Invalid Unicode property escape." +- name: ID_EXPECTED + id: 122 + message: "Identifier expected." -- name: UNEXPECTED_TOKEN_AS - id: 95 - message: "Unexpected token, expected 'as'." +- name: ILLEGALE_CONTINUE + id: 165 + message: "Illegal continue statement." -- name: OPTIONAL_VAR_IN_FOR_OF - id: 96 - message: "Optional variable is not allowed in for of statements." +- name: ILLEGAL_AWAIT_IN_ASYNC_FUN + id: 65 + message: "Illegal await-expression in formal parameters of async function." -- name: FOR_AWAIT_OF_VAR_NOT_INIT - id: 97 - message: "for-await-of loop variable declaration may not have an initializer." +- name: ILLEGAL_BREAK + id: 209 + message: "Illegal break statement." -- name: VARIANCE_NOD_ALLOWED - id: 98 - message: "Variance modifier is not allowed here." +- name: ILLEGAL_EXPRESSION_WRAP + id: 196 + message: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses." -- name: FUN_PARAM_THIS_MISSING_TYPE - id: 99 - message: "The function parameter 'this' must explicitly specify the typeAnnotation." +- name: ILLEGAL_NEW_LINE + id: 172 + message: "Illegal newline after throw." -- name: MISSING_INIT_OR_CONST_DEC - id: 100 - message: "Missing initializer in const declaration." +- name: ILLEGAL_START_EXPRESSION + id: 208 + message: "Illegal start of expression." -- name: CATCH_CLAUSE_VAR_HAS_INIT - id: 101 - message: "Catch clause variable cannot have an initializer." +- name: ILLEGAL_START_STRUCT_CLASS + id: 40 + message: "Illegal start of {} expression." -- name: ASTERIKS_NOT_ALLOWED_IN_SELECTIVE_BINDING - id: 102 - message: "The '*' token is not allowed as a selective binding (between braces)." +- name: ILLEGAL_USE_STRICT + id: 199 + message: "Illegal 'use strict' directive in function with non-simple parameter list." -- name: ONLY_THROWS_IN_FUN_TYPE - id: 103 - message: "Only 'throws' can be used with function types." +- name: IMPLEMENTS_CLAUSE_EMPTY + id: 185 + message: "Implements clause can not be empty." -- name: DECALRE_IN_AMBIENT_CONTEXT - id: 104 - message: "A 'declare' modifier cannot be used in an already ambient context." +- name: IMPLICIT_OCTAL_NOT_ALLOWED + id: 257 + message: "Implicit octal literal not allowed." -- name: MISSING_INIT_OR_TYPE - id: 105 - message: "Variable must be initialized or it's type must be declared." +- name: IMPORT_EXPORT_ONLY_AT_TOP_LEVEL + id: 166 + message: "'import' and 'export' may only appear at the top level." -- name: ASYNC_IN_AMBIENT_CONTEXT - id: 106 - message: "The modifier async cannot be used in an ambient context." +- name: IMPORT_META_DIRECT_EVAL + id: 48 + message: "'import.Meta' is not allowed in direct eval in module code." -- name: MODIFIERS_OF_GET_SET_LIMITED - id: 107 - message: "Modifiers of getter and setter are limited to ('abstract', 'static', 'final', 'override', 'native')." +- name: IMPORT_META_ONLY_MODULE + id: 69 + message: "'import.Meta' may appear only with 'sourceType: module'." -- name: ESCAPE_SEQUENCES_IN_AS - id: 108 - message: "Escape sequences are not allowed in 'as' keyword." +- name: IMPORT_TOP_LEVEL + id: 226 + message: "Import declarations can only be used on the top level and before any other declaration, top level statement or + directive." + +- name: IMPROPER_NESTING_CLASS + id: 233 + message: "Unexpected token. A constructor, method, accessor, or property was expected." + +- name: IMPROPER_NESTING_INTERFACE + id: 234 + message: "Property or signature expected." -- name: LOCAL_TYPE_DEC_NO_IMPLEMENTED - id: 109 - message: "Local type declaration (class, struct, interface and enum) support is not yet implemented." +- name: INDEX_MISSING_IDENTIFIER + id: 21 + message: "Return type of index signature from exported class or interface need to be identifier." -- name: TYPE_IMPORT_MISSING_SELECTIVE_BINDING - id: 110 - message: "Type import requires selective binding to define the required imported elements." +- name: INDEX_MISSING_TYPE + id: 20 + message: "An index signature must have a type annotation." -- name: EXPORT_IN_NAMESPACE - id: 111 - message: "Export declarations are not permitted in a namespace." +- name: INDEX_TYPE_EXPECTED + id: 17 + message: "Index type expected in index signature." -- name: UNEXPECTED_TOKEN_ID - id: 112 - message: "Unexpected token, expected an identifier." +- name: INDEX_TYPE_NOT_NUMBER + id: 18 + message: "Index type must be number in index signature." -- name: ANNOTATION_NOT_ALLOWED - id: 113 - message: "Annotations cannot be applied here." +- name: INITIALIZERS_INTERFACE_PROPS + id: 123 + message: "Initializers are not allowed on interface properties." -- name: ANNOTATION_ONLY_TOP_LEVEL - id: 114 - message: "Annotations can only be declared at the top level." +- name: INITIALIZERS_IN_AMBIENT_CONTEXTS + id: 125 + message: "Initializers are not allowed in ambient contexts." -- name: DUPLICATED_MODIFIER - id: 115 - message: "Duplicated modifier is not allowed." +- name: INIT_MODULE_DECLARATION_POSITION + id: 322 + message: "initModule() must only be called immediately after the import statement, and before any other declarations or + statements." -- name: NATIVE_METHOD_ASYNC - id: 116 - message: "Native method cannot be async." +- name: INSERT_NODE_ABSENT + id: 10 + message: "There is no any node to insert at the placeholder position." -- name: KEYWORD_CONTAINS_ESCAPED_CHARS - id: 117 - message: "Keyword must not contain escaped characters." +- name: INSUFFICIENT_PARAM_IN_ARROW_FUN + id: 64 + message: "Insufficient formal parameter in arrow function." -- name: ABSTRACT_METHOD_ASYNC - id: 118 - message: "Abstract method cannot be async." +- name: INTERFACE_DEC_IMPLEMENTS + id: 177 + message: "Interface declaration cannot have 'implements' clause." - name: INTERFACE_FIELDS_TYPE_ANNOTATION id: 119 message: "Interface fields must have type annotation." -- name: ACCESS_BEFORE_FIELD_METHOD - id: 120 - message: "Access modifier must precede field and method modifiers." +- name: INTERFACE_MEMBER_INIT_NOT_ALLOWED + id: 180 + message: "Interface member initialization is prohibited." -- name: FIELD_TPYE_ANNOTATION_MISSING - id: 121 - message: "Field type annotation expected." +- name: INVALIDE_CHAR_CLASS + id: 79 + message: "Invalid character class." -- name: ID_EXPECTED - id: 122 - message: "Identifier expected." +- name: INVALID_ACCESSOR + id: 159 + message: "Invalid accessor." -- name: INITIALIZERS_INTERFACE_PROPS - id: 123 - message: "Initializers are not allowed on interface properties." +- name: INVALID_ARGUMENT_ETSNOLINT + id: 278 + message: "Invalid argument for ETSNOLINT!" -- name: UNEXPECTED_TOKEN_PRIVATE_ID - id: 124 - message: "Unexpected token, expected 'private' or identifier." +- name: INVALID_ARGUMENT_PASSED + id: 26 + message: "Invalid argument passed to '{}'." -- name: INITIALIZERS_IN_AMBIENT_CONTEXTS - id: 125 - message: "Initializers are not allowed in ambient contexts." +- name: INVALID_ASSERT + id: 93 + message: "Invalid assertion." -- name: VAR_DEC_EXPECTED - id: 126 - message: "Variable declaration expected." +- name: INVALID_BIGINT + id: 255 + message: "Invalid BigInt number." -- name: CONFLICTING_FIELD_MODIFIERS - id: 127 - message: "Conflicting modifiers '!' and '?' on field." +- name: INVALID_CAPTURING_GROUP + id: 76 + message: "Invalid capturing group." -- name: VALUE_IS_NOT_SET - id: 128 - message: "You didn't set the value." +- name: INVALID_CHAR + id: 77 + message: "Invalid character." -- name: TYPE_ALIAS_ONLY_TOP_LEVEL - id: 129 - message: "Type alias is allowed only as top-level declaration." +- name: INVALID_CHAR_ESCAPE + id: 258 + message: "Invalid character escape sequence." -- name: INVALID_RIGHT_INSTANCEOF - id: 130 - message: "Invalid right-hand side in 'instanceof' expression." +- name: INVALID_CLASS_FIELD + id: 12 + message: "Cannot parse class field definition property." -- name: IDENTIFIER_EXPECTED - id: 131 - message: "Identifier is needed here." +- name: INVALID_CLASS_METHOD + id: 13 + message: "Cannot parse class method definition property." -- name: DEFAULT_UNDEF_NOT_ALLOWED - id: 132 - message: "Not enable default value with default undefined." +- name: INVALID_CLOSING_PARENTHESIS + id: 75 + message: "Invalid closing parenthesis." -- name: DEFAULT_ONLY_FOR_OPTIONAL - id: 133 - message: "Default value is allowed only for optional parameters." +- name: INVALID_CONTROL_ESCAPE + id: 92 + message: "Invalid control escape." -- name: NAMESPACE_ONLY_TOP_OR_IN_NAMESPACE - id: 134 - message: "Namespace is allowed only at the top level or inside a namespace." +- name: INVALID_DECIMAL_ESCAPE + id: 81 + message: "Invalid decimal escape." -- name: NESTED_FUNCTIONS_NOT_ALLOWED - id: 135 - message: "Nested functions are not allowed." +- name: INVALID_DECORATOR_CONSTRUCTOR + id: 201 + message: "The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and + 'native' modifiers." -- name: SPREAD_MUST_BE_LAST_IN_TUPLE - id: 136 - message: "Spread type must be at the last index in the tuple type." +- name: INVALID_DESTRUCTURING_TARGET + id: 49 + message: "Invalid destructuring assignment target." -- name: PRIMITIVE_NOT_ALLOWED - id: 137 - message: "Primitive type is not allowed here." +- name: INVALID_DIGIT + id: 266 + message: "Invalid digit." -- name: INVALID_TYPE - id: 138 - message: "Invalid Type." +- name: INVALID_ENUM_TYPE + id: 35 + message: "Invalid enum initialization type." -- name: SPREAD_TYPE_MUST_BE_ARRAY - id: 139 - message: "Spread type must be an array type." +- name: INVALID_ESCAPE + id: 87 + message: "Invalid escape." -- name: TYPE_ANNOTATION_FOR_CONSTRUCTOR - id: 140 - message: "Type annotation isn't allowed for constructor." +- name: INVALID_EXPORT_DEFAULT + id: 42 + message: "Can not export annotation default." -- name: READONLY_ONLY_ON_ARRAY_OR_TUPLE - id: 141 - message: "'readonly' type modifier is only permitted on resizable array and tuple types." +- name: INVALID_GROUP + id: 85 + message: "Invalid group." -- name: OPTIONAL_TYPES_IN_TUPLE_NOT_IMPLEMENTED - id: 142 - message: "Optional types in tuples are not yet implemented." +- name: INVALID_GROUP_NAME + id: 84 + message: "Invalid group name." -- name: ONLY_SPREAD_AT_LAST_INDEX - id: 143 - message: "Only one spread type declaration allowed, at the last index." +- name: INVALID_HEX_ESCAPE + id: 83 + message: "Invalid hex escape." -- name: CLASS_FIELD_CONSTRUCTOR - id: 144 - message: "Classes may not have a field named 'constructor'." +- name: INVALID_IDENTIFIER_PART + id: 263 + message: "Invalid identifier part." -- name: NOT_ALLOWED_USER_DEFINED_TYPE - id: 145 - message: "Cannot be used as user-defined type." +- name: INVALID_INIT_IN_PACKAGE + id: 288 + message: "Non-constant initializer of Package should be apply in Initializer Block." -- name: EXTENSION_ACCESSOR_RECEIVER - id: 146 - message: "Extension Accessor must have a receiver." +- name: INVALID_INSERT_NODE + id: 11 + message: "Inserting node type differs from that required by format specification." -- name: UNEXPECTED_TOKEN_ID_FUN - id: 147 - message: "Unexpected token, expected function identifier." +- name: INVALID_LEFT_FOR_IN + id: 174 + message: "Invalid left-hand side in for-in statement." -- name: UNEXPECTED_ARROWPARAM_ELEMENT - id: 148 - message: "Unexpected ArrowParameter element." +- name: INVALID_LEFT_FOR_IN_OF + id: 167 + message: "Invalid left-hand side in 'For[In/Of]Statement'." -- name: SPECIAL_METHOD_CONSTRUCTOR - id: 149 - message: "Constructor can not be special method." +- name: INVALID_LEFT_HAND_IN_FOR_OF + id: 211 + message: "Invalid left-hand side in 'for' statement: must have a single binding." -- name: TRAILING_COMMA_NOT_ALLOWED - id: 150 - message: "Trailing comma is not allowed in this context." +- name: INVALID_LEFT_IN_PREFIX + id: 71 + message: "Invalid left-hand side in prefix operation." -- name: UNEXPECTED_TOKEN_STRING_LITERAL - id: 151 - message: "Unexpected token, expected string literal." +- name: INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING + id: 204 + message: "Invalid left-hand side in array destructuring pattern." + +- name: INVALID_LEFT_SIDE_IN_ASSIGNMENT + id: 72 + message: "Invalid left-hand side in assignment expression." -- name: RESTPARAM_INIT - id: 152 - message: "RestParameter does not support an initializer." +- name: INVALID_LEFT_SITE_OPERATOR + id: 53 + message: "Invalid left-hand side operator." -- name: UNEXPECTED_MODIFIER - id: 153 - message: "Unexpected modifier." +- name: INVALID_NAME_BACKREFERENCE + id: 89 + message: "Invalid named backreference." -- name: PRIVATE_FIELD_REDEC - id: 154 - message: "Private field has already been declared." +- name: INVALID_NODE_NUMBER + id: 8 + message: "Invalid node number in format expression." -- name: STATIC_PROPERTY_PROTOTYPE - id: 155 - message: "Classes may not have static property named prototype." +- name: INVALID_NODE_TYPE + id: 9 + message: "Invalid node type in format expression." -- name: RESTPARAM_ID_IN_DEC_CONTEXT - id: 156 - message: "RestParameter must be followed by an identifier in declaration contexts" +- name: INVALID_NON_CAPTURING_GROUP + id: 90 + message: "Invalid non-capturing group." -- name: DECLARE_MODIFIER_ON_INVALID_CLASS_ELEMENT - id: 157 - message: "'declare modifier cannot appear on class elements of this kind." +- name: INVALID_NUM + id: 249 + message: "Invalid number." -- name: FUNC_PARAM_THIS_FIRST - id: 158 - message: "Function Parameter 'this' must be the first." +- name: INVALID_NUMERIC_LIT + id: 251 + message: "Invalid numeric literal." -- name: INVALID_ACCESSOR - id: 159 - message: "Invalid accessor." +- name: INVALID_NUMERIC_SEP + id: 254 + message: "Invalid numeric separator." -- name: UNEXPECTED_TOKEN_IN_PRIVATE - id: 160 - message: "Unexpected token in private field." +- name: INVALID_NUMERIC_SEP_AT_END_OF_NUM + id: 250 + message: "Numeric separators are not allowed at the end of numeric literals." -- name: WITH_DEPRECATED - id: 161 - message: "'With' is deprecated and not supported any more." +- name: INVALID_OCTAL_DIGIT + id: 239 + message: "Invalid octal digit." -- name: UNDEFINED_LABEL - id: 162 - message: "Undefined label." +- name: INVALID_PACKAGE_TOP_LEVEL_STMT + id: 291 + message: "Invalid package toplevel statement" -- name: RETURN_IN_FUN_BODY - id: 163 - message: "return keyword should be used in function body." +- name: INVALID_QUANTIFIER + id: 88 + message: "Invalid quantifier, nothing to repeat." -- name: FOR_IN_LOOP_HAS_INIT - id: 164 - message: "for-in loop variable declaration may not have an initializer." +- name: INVALID_REGEX_FLAG + id: 246 + message: "Invalid RegExp flag." -- name: ILLEGALE_CONTINUE - id: 165 - message: "Illegal continue statement." +- name: INVALID_REST_ELEMENT + id: 55 + message: "Invalid rest element." -- name: IMPORT_EXPORT_ONLY_AT_TOP_LEVEL - id: 166 - message: "'import' and 'export' may only appear at the top level." +- name: INVALID_RIGHT_INSTANCEOF + id: 130 + message: "Invalid right-hand side in 'instanceof' expression." -- name: INVALID_LEFT_FOR_IN_OF - id: 167 - message: "Invalid left-hand side in 'For[In/Of]Statement'." +- name: INVALID_SHORTHAND_PROPERTY_INITIALIZER + id: 286 + message: "Invalid shorthand property initializer." -- name: FOR_OF_LOOP_HAS_INIT - id: 168 - message: "for-of loop variable declaration may not have an initializer." +- name: INVALID_TYPE + id: 138 + message: "Invalid Type." -- name: MISSING_CATCH_OR_FINALLY - id: 169 - message: "Missing catch or finally clause." +- name: INVALID_TYPE_ANNOTATION_IN_FOR + id: 212 + message: "Type annotation is not allowed when existing variable is used as loop iterator in 'for' statement." -- name: UNEXPECTED_TOKEN_WHILE - id: 170 - message: "Unexpected token, expected 'while'." +- name: INVALID_UNICODE_ESCAPE + id: 91 + message: "Invalid Unicode escape." -- name: MULTIPLE_DEFAULT - id: 171 - message: "Multiple default clauses." +- name: INVALID_UNICODE_PROP_ESCAPE + id: 94 + message: "Invalid Unicode property escape." -- name: ILLEGAL_NEW_LINE - id: 172 - message: "Illegal newline after throw." +- name: INVALID_VAL_ANNOTATION_FIELD + id: 27 + message: "Invalid value for annotation field, expected a constant literal." -- name: GENERATORS_ONLY_TOP_LEVEL_OR_INSIDE_BLOCK - id: 173 - message: "Generators can only be declared at the top level or inside a block." +- name: KEYWORD_CONTAINS_ESCAPED_CHARS + id: 117 + message: "Keyword must not contain escaped characters." -- name: INVALID_LEFT_FOR_IN - id: 174 - message: "Invalid left-hand side in for-in statement." +- name: LABEL_ALREADY_DECLARED + id: 214 + message: "Label already declared." + +- name: LATE_INITIALIZATION_FIELD_HAS_DEFAULT_VALUE + id: 304 + message: "Late-initialized field cannot have default value." - name: LEXICAL_DEC_NOT_ALLOWED_IN_SINGLE_STATEMENT_CONTEXT id: 175 message: "Lexical declaration is not allowed in single statement context." -- name: TYPE_PARAM_DEC_EXPECTED - id: 176 - message: "Type parameter declaration expected." - -- name: INTERFACE_DEC_IMPLEMENTS - id: 177 - message: "Interface declaration cannot have 'implements' clause." - -- name: UNEXPECTED_TOKEN_ENUM - id: 178 - message: "Unexpected token in enum member." - -- name: REQUIRED_TYPE_PARAM_AFTER_OPTIONAL - id: 179 - message: "Required type parameters may not follow optional type parameters." +- name: LITERAL_VALUE_IDENT + id: 315 + message: "Number, string or computed value property name '{}' is not allowed, use classes to access data by property names + that are identifiers" -- name: INTERFACE_MEMBER_INIT_NOT_ALLOWED - id: 180 - message: "Interface member initialization is prohibited." +- name: LOCAL_CLASS_ACCESS_MOD + id: 30 + message: "Local class or interface declaration members can not have access modifies." -- name: ONLY_AMBIENT_MODULES_QUOTED_NAMES - id: 181 - message: "Only ambient modules can use quoted names." +- name: LOCAL_TYPE_DEC_NO_IMPLEMENTED + id: 109 + message: "Local type declaration (class, struct, interface and enum) support is not yet implemented." -- name: BINDING_ARGS_INVALID - id: 182 - message: "Binding 'arguments' in strict mode is invalid." +- name: META_PROP_FOR_IMPORT + id: 68 + message: "The only valid meta property for import is import.Meta." -- name: DECORATORS_INVALID - id: 183 - message: "Decorators are not valid here." +- name: MISSING_CATCH_OR_FINALLY + id: 169 + message: "Missing catch or finally clause." -- name: ABSTRACT_METHODS_ONLY_IN_ABSTRACT_CLASS - id: 184 - message: "Abstract methods can only appear within an abstract class." +- name: MISSING_CATCH_OR_FINALLY_AFTER_TRY + id: 39 + message: "A try statement should contain either finally clause or at least one catch clause." -- name: IMPLEMENTS_CLAUSE_EMPTY - id: 185 - message: "Implements clause can not be empty." +- name: MISSING_INIT_FOR_CONST_PACKAGE_PROP + id: 294 + message: "Missing initialization for const package property" - name: MISSING_INIT_IN_DEST_DEC id: 186 message: "Missing initializer in destructuring declaration." -- name: UNEXPECTED_TOKEN_FOR_PARAM - id: 187 - message: "Unexpected '?' for parameter." - -- name: TYPE_EXPECTED - id: 188 - message: "Type expected." +- name: MISSING_INIT_OR_CONST_DEC + id: 100 + message: "Missing initializer in const declaration." -- name: OVERRIDE_IN_INTERFACE - id: 189 - message: "'override' modifier cannot appear in interfaces." +- name: MISSING_INIT_OR_TYPE + id: 105 + message: "Variable must be initialized or it's type must be declared." -- name: BINDING_EVAL_INVALID - id: 190 - message: "Binding 'eval' in strict mode is invalid." +- name: MISSING_LOOP_AFTER_LABEL + id: 38 + message: "Label must be followed by a loop statement." -- name: TYPE_PARAM_LIST_EMPTY - id: 191 - message: "Type parameter list cannot be empty." +- name: MISSING_LOOP_BODY + id: 300 + message: "Missing body in {} statement" -- name: NO_DEFAULT_FOR_REST - id: 192 - message: "Rest parameter cannot have the default value." +- name: MISSING_LOOP_CONDITION + id: 301 + message: "Missing condition in {} statement" -- name: ONLY_ARRAY_OR_TUPLE_FOR_REST - id: 193 - message: "Rest parameter should be either array or tuple type." +- name: MISSING_TYPE_ANNOTATION + id: 1 + message: "Missing type annotation for property '{}'." -- name: EXPLICIT_PARAM_TYPE - id: 194 - message: "Parameter declaration should have an explicit type annotation." +- name: MODIFIERS_OF_GET_SET_LIMITED + id: 107 + message: "Modifiers of getter and setter are limited to ('abstract', 'static', 'final', 'override', 'native')." -- name: EXPECTED_ARROW_SAME_LINE - id: 195 - message: "expected '=>' on the same line after an argument list, got line terminator." +- name: MORE_INDEXER + id: 326 + message: "Only one index signature can exist in a class" -- name: ILLEGAL_EXPRESSION_WRAP - id: 196 - message: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses." +- name: MULTIPLE_CONSTRUCTOR_IMPLEMENTATIONS + id: 206 + message: "Multiple constructor implementations are not allowed." -- name: ASYNC_METHOD_LINE_TERM - id: 197 - message: "Async methods cannot have a line terminator between 'async' and the property name." +- name: MULTIPLE_DEFAULT + id: 171 + message: "Multiple default clauses." -- name: STRICT_MODE_FUNC_DECL - id: 198 - message: "In strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement." +- name: MULTIPLE_STATIC_BLOCK + id: 34 + message: "Only one static block is allowed in one namespace or class." -- name: ILLEGAL_USE_STRICT - id: 199 - message: "Illegal 'use strict' directive in function with non-simple parameter list." +- name: NAMESPACE_ANNOTATION_CONFLICT + id: 7 + message: "Annotation conflict! Multiple namespace declarations for '{}' cannot each have annotations." -- name: ASYNC_CONSTRUCTOR - id: 200 - message: "Constructor should not be async." +- name: NAMESPACE_MERGE_ERROR + id: 6 + message: "Unable to merge namespaces '{}', because their modifiers are different." -- name: INVALID_DECORATOR_CONSTRUCTOR - id: 201 - message: "The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and 'native' modifiers." +- name: NAMESPACE_ONLY_TOP_OR_IN_NAMESPACE + id: 134 + message: "Namespace is allowed only at the top level or inside a namespace." -- name: ASYNC_FLAG_ONLY_FOR_TOP_FUN - id: 202 - message: "'async' flags must be used for functions only at top-level." +- name: NAME_CANNOT_BE_EXPORTED_AND_TYPE_EXPORTED + id: 283 + message: "Name '{}' cannot be exported and type exported at the same time." - name: NATIVE_FLAG_ONLY_FOR_TOP_FUN id: 203 message: "'native' flags must be used for functions only at top-level." -- name: INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING - id: 204 - message: "Invalid left-hand side in array destructuring pattern." - -- name: GET_ACCESSOR_MUST_BE_AT_LEAST_AS_ACCESSIBLE - id: 205 - message: "A get accessor must be at least as accessible as the setter." - -- name: MULTIPLE_CONSTRUCTOR_IMPLEMENTATIONS - id: 206 - message: "Multiple constructor implementations are not allowed." - -- name: EVAL_OR_ARGUMENTS_IN_STRICT_MODE - id: 207 - message: "'eval' or 'arguments' can't be defined or assigned to in strict mode code." - -- name: ILLEGAL_START_EXPRESSION - id: 208 - message: "Illegal start of expression." +- name: NATIVE_METHOD_ASYNC + id: 116 + message: "Native method cannot be async." -- name: ILLEGAL_BREAK - id: 209 - message: "Illegal break statement." +- name: NESTED_FUNCTIONS_NOT_ALLOWED + id: 135 + message: "Nested functions are not allowed." -- name: ANNOTATION_DECLARATION_ACCESS_MODIFIER - id: 210 - message: "Annotation declaration can not have access modifier." +- name: NEWLINE_NOT_ALLOWED_IN_STRING + id: 265 + message: "Newline is not allowed in strings" -- name: INVALID_LEFT_HAND_IN_FOR_OF - id: 211 - message: "Invalid left-hand side in 'for' statement: must have a single binding." +- name: NEW_TARGET_IS_NOT_ALLOWED + id: 73 + message: "'new.Target' is not allowed here." -- name: INVALID_TYPE_ANNOTATION_IN_FOR - id: 212 - message: "Type annotation is not allowed when existing variable is used as loop iterator in 'for' statement." +- name: NEW_TARGET_WITH_ESCAPED_CHARS + id: 74 + message: "'new.Target' must not contain escaped characters." -- name: AWAIT_RESERVED_IDENTIFIER_IN_MODULE - id: 213 - message: "'await' is a reserved identifier in module code." +- name: NEW_WITH_IMPORT + id: 60 + message: "Cannot use new with import(...)." -- name: LABEL_ALREADY_DECLARED - id: 214 - message: "Label already declared." +- name: NON_OCTAL_DECIAML_INTEGER_LIT_IN_STRICT_MODE + id: 256 + message: "NonOctalDecimalIntegerLiteral is not enabled in strict mode code." -- name: DUPLICATED_IDENTIFIER - id: 215 - message: "Duplicated identifier." +- name: NOT_ALLOWED_USER_DEFINED_TYPE + id: 145 + message: "Cannot be used as user-defined type." -- name: PARAM_CANNOT_HAVE_QUESTION_MARK - id: 216 - message: "Parameter cannot have question mark and initializer." +- name: NOT_AS_OBJECT + id: 318 + message: "{} cannot be used as object." -- name: BINDING_PATTERN_PARAM_CANNOT_BE_OPTIONAL - id: 217 - message: "A binding pattern parameter cannot be optional in an implementation signature." +- name: NO_DEFAULT_FOR_REST + id: 192 + message: "Rest parameter cannot have the default value." -- name: REST_PARAM_CANNOT_BE_OPTIONAL - id: 218 - message: "A rest parameter cannot be optional." +- name: NULLISH_COALESCING_MISSING_PARENS + id: 59 + message: "Nullish coalescing operator ?? requires parens when mixing with logical operators." -- name: REQUIRED_PARAM_AFTER_OPTIONAL - id: 219 - message: "A required parameter cannot follow an optional parameter." +- name: NUMERIC_SEP_UNDERSCORE_IN_NUMBER + id: 252 + message: "Numeric separator '_' is not allowed in numbers that start with '0'." -- name: SPECIAL_PREDEFINED_METHOD_CANNOT_BE_ASYNC - id: 220 - message: "The special predefined method '{}' cannot be asynchronous." +- name: OBJECT_PATTER_CONTAIN_METHODS + id: 62 + message: "Object pattern can't contain methods." -- name: SPECIAL_PREDEFINED_METHOD_SHOULD_HAVE_ONE_PARAM - id: 221 - message: "The special predefined method '{}' should have exactly one required parameter." +- name: OCTAL_ESCAPE_IN_TEMPLATE_STRINGS + id: 247 + message: "Octal escape sequences are not allowed in template strings." -- name: SPECIAL_PREDEFINED_METHOD_SHOULD_HAVE_TWO_PARAMS - id: 222 - message: "The special predefined method '{}' should have exactly two required parameter." +- name: ONLY_AMBIENT_MODULES_QUOTED_NAMES + id: 181 + message: "Only ambient modules can use quoted names." -- name: SPECIAL_PREDEFINED_METHOD_SHOULD_NOT_HAVE_PARAMS - id: 223 - message: "The special predefined method '{}' should not have parameters." +- name: ONLY_ARRAY_OR_TUPLE_FOR_REST + id: 193 + message: "Rest parameter should be either array or tuple type." -- name: IDENTIFIER_EXPECTED_HERE - id: 224 - message: "Identifier expected, got '{}'." +- name: ONLY_CALL_AFTER_LAUNCH + id: 37 + message: "Only call expressions are allowed after 'launch'." -- name: TYPE_ALIAS_INVALID_NAME - id: 225 - message: "Type alias name cannot be '{}'." +- name: ONLY_CONSTANT_ALLOWED + id: 292 + message: "Only constant expression is expected in the field" -- name: IMPORT_TOP_LEVEL - id: 226 - message: "Import declarations can only be used on the top level and before any other declaration, top level statement or directive." +- name: ONLY_CONSTANT_EXPRESSION + id: 272 + message: "Only constant expression is expected in the field" -- name: UNEXPECTED_TOKEN_PARAM - id: 227 - message: "Unexpected token '{}'." +- name: ONLY_EXPORT_CLASS_OR_INTERFACE + id: 41 + message: "Can only type export class or interface." -- name: UNEXPECTED_TOKEN_EXPECTED_PARAM - id: 228 - message: "Unexpected token, expected '{}'." +- name: ONLY_SPREAD_AT_LAST_INDEX + id: 143 + message: "Only one spread type declaration allowed, at the last index." -- name: UNEXPECTED_TOKEN_EXPECTED_PARAM_OR_PARAM - id: 229 - message: "Unexpected token, expected '{}' or '{}'." +- name: ONLY_STRING_LITERAL_IN_INIT_MODULE + id: 321 + message: "initModule() only accept string literal as argument." -- name: EXPECTED_PARAM_GOT_PARAM - id: 230 - message: "Expected '{}', got '{}'." +- name: ONLY_THROWS_IN_FUN_TYPE + id: 103 + message: "Only 'throws' can be used with function types." -- name: UNEXPECTED_TOKEN_PARAM_EXPECTED_CASE_OR_DEFAULT - id: 231 - message: "Unexpected token '{}', expected 'case' or 'default'." +- name: OPTIONAL_TYPES_IN_TUPLE_NOT_IMPLEMENTED + id: 142 + message: "Optional types in tuples are not yet implemented." -- name: PARAM_MODIFIER_CANNOT_APPEAR_ON_PARAMETER - id: 232 - message: "'{}' modifier cannot appear on a parameter." +- name: OPTIONAL_VARIABLE + id: 306 + message: "Optional variable is deprecated and no longer supported." -- name: IMPROPER_NESTING_CLASS - id: 233 - message: "Unexpected token. A constructor, method, accessor, or property was expected." +- name: OPTIONAL_VAR_IN_FOR_OF + id: 96 + message: "Optional variable is not allowed in for of statements." -- name: IMPROPER_NESTING_INTERFACE - id: 234 - message: "Property or signature expected." +- name: OVERLOAD_MODIFIERS + id: 323 + message: "Overload Declaration only allow use modifier 'static' | 'async'." -- name: UNEXPECTED_DEFAULT - id: 235 - message: "Unexpected token 'default'. Only declarations are allowed after 'export default'." +- name: OVERRIDE_IN_INTERFACE + id: 189 + message: "'override' modifier cannot appear in interfaces." -- name: REST_PARAM_LAST - id: 236 - message: "Rest parameter should be the last one." +- name: PACKAGE_MODULE_IMPORT_OWN_PACKAGE + id: 3 + message: "Package module cannot import from a file in it's own package." -- name: READONLY_TYPE_EXPECTED - id: 237 - message: "Readonly utility type expected but readonly found." +- name: PACKAGE_MULTIPLE_STATIC_BLOCK + id: 289 + message: "static block cannot apply to multi-files for one package" -- name: PROHIBITED_ACCESS_MODIFIER_IN_AMBIENT_CLASS - id: 238 - message: "Methods or fields should not be decorated with {} in ambient class." +- name: PARAM_CANNOT_HAVE_QUESTION_MARK + id: 216 + message: "Parameter cannot have question mark and initializer." -- name: INVALID_OCTAL_DIGIT - id: 239 - message: "Invalid octal digit." +- name: PARAM_MODIFIER_CANNOT_APPEAR_ON_PARAMETER + id: 232 + message: "'{}' modifier cannot appear on a parameter." -- name: UNEXPECTED_THIS - id: 240 - message: "Unexpected 'this' keyword in non-receiver context." +- name: PREDEFINED_TYPE_AS_IDENTIFIER + id: 295 + message: "{} is a predefined type, cannot be used as an identifier" -- name: SETTER_NO_RETURN_TYPE - id: 241 - message: "Setter must not have return type even if it is void." +- name: PRIMITIVE_NOT_ALLOWED + id: 137 + message: "Primitive type is not allowed here." -- name: USING_RESERVED_NAME_AS_VARIABLE_OR_TYPE_NAME - id: 242 - message: "'{}' is reserved and cannot be used as a variable/type name" +- name: PRIVATE_FIELD_MISMATCH + id: 302 + message: "Private field '{}' must be declared in an enclosing class" -- name: UNHANDLED_THROW_IN_INITIALIZER - id: 243 - message: "Unhandled throw statement." +- name: PRIVATE_FIELD_REDEC + id: 154 + message: "Private field has already been declared." -- name: EXPORT_DEFAULT_NO_REEXPORT - id: 244 - message: "Cannot use 'export default' in re-export context" +- name: PRIVATE_IDENTIFIER_NOT_CONSTRUCTOR + id: 267 + message: "Private identifier can not be constructor." -- name: UNTERMINATED_MULTI_LINE_COMMENT - id: 245 - message: "Unterminated multi-line comment." +- name: PRIVATE_IDENTIFIER_NUMBER + id: 269 + message: "Private identifier name can not be number." -- name: INVALID_REGEX_FLAG - id: 246 - message: "Invalid RegExp flag." +- name: PRIVATE_IDENTIFIER_STRING + id: 268 + message: "Private identifier name can not be string." -- name: OCTAL_ESCAPE_IN_TEMPLATE_STRINGS - id: 247 - message: "Octal escape sequences are not allowed in template strings." +- name: PRIVATE_INTERFACE_MISSING_BODY + id: 32 + message: "Private interface methods must have body." -- name: HEXADECIMAL_EXPECTED - id: 248 - message: "Hexadecimal digit expected." +- name: PROHIBITED_ACCESS_MODIFIER_IN_AMBIENT_CLASS + id: 238 + message: "Methods or fields should not be decorated with {} in ambient class." -- name: INVALID_NUM - id: 249 - message: "Invalid number." +- name: QUANTIFIER_OUT_OF_ORDER + id: 78 + message: "Quantifier range out of order." -- name: INVALID_NUMERIC_SEP_AT_END_OF_NUM - id: 250 - message: "Numeric separators are not allowed at the end of numeric literals." +- name: READONLY_INTERFACE_METHOD + id: 33 + message: "Modifier 'readonly' cannot be applied to an interface method." -- name: INVALID_NUMERIC_LIT - id: 251 - message: "Invalid numeric literal." +- name: READONLY_ONLY_ON_ARRAY_OR_TUPLE + id: 141 + message: "'readonly' type modifier is only permitted on resizable array and tuple types." -- name: NUMERIC_SEP_UNDERSCORE_IN_NUMBER - id: 252 - message: "Numeric separator '_' is not allowed in numbers that start with '0'." +- name: READONLY_TYPE_EXPECTED + id: 237 + message: "Readonly utility type expected but readonly found." -- name: UNTERMINATED_STRING - id: 253 - message: "Unterminated string." +- name: REQUIRED_PARAM_AFTER_DEFAULT + id: 14 + message: "Required parameter follows default parameter(s)." -- name: INVALID_NUMERIC_SEP - id: 254 - message: "Invalid numeric separator." +- name: REQUIRED_PARAM_AFTER_OPTIONAL + id: 219 + message: "A required parameter cannot follow an optional parameter." -- name: INVALID_BIGINT - id: 255 - message: "Invalid BigInt number." +- name: REQUIRED_TYPE_PARAM_AFTER_OPTIONAL + id: 179 + message: "Required type parameters may not follow optional type parameters." -- name: NON_OCTAL_DECIAML_INTEGER_LIT_IN_STRICT_MODE - id: 256 - message: "NonOctalDecimalIntegerLiteral is not enabled in strict mode code." +- name: RESTPARAM_ID_IN_DEC_CONTEXT + id: 156 + message: "RestParameter must be followed by an identifier in declaration contexts" -- name: IMPLICIT_OCTAL_NOT_ALLOWED - id: 257 - message: "Implicit octal literal not allowed." +- name: RESTPARAM_INIT + id: 152 + message: "RestParameter does not support an initializer." -- name: INVALID_CHAR_ESCAPE - id: 258 - message: "Invalid character escape sequence." +- name: REST_AND_DEFAULT_SAME_TIME + id: 15 + message: "Both optional and rest parameters are not allowed in function's parameter list." -- name: UNEXPECTED_TOKEN_EXPECTED_BACKTICK_OR_DOLLAR_LBRACE - id: 259 - message: "Unexpected token, expected '${' or '`'" +- name: REST_PARAM_CANNOT_BE_OPTIONAL + id: 218 + message: "A rest parameter cannot be optional." -- name: UNTERMINATED_REGEX - id: 260 - message: "Unterminated RegExp." +- name: REST_PARAM_LAST + id: 236 + message: "Rest parameter should be the last one." -- name: UNSUPPORTED_CHAR_LIT - id: 261 - message: "Unsupported character literal." +- name: REST_PARAM_NOT_LAST + id: 67 + message: "Rest parameter must be the last formal parameter." -- name: TOO_LARGE_NUM - id: 262 - message: "Number is too large." +- name: RETURN_IN_FUN_BODY + id: 163 + message: "return keyword should be used in function body." -- name: INVALID_IDENTIFIER_PART - id: 263 - message: "Invalid identifier part." +- name: RETURN_WITH_VALUE + id: 287 + message: "Unexpected return value." -- name: UNEXPECTED_STRICT_MODE_RESERVED_KEYWORD - id: 264 - message: "Unexpected strict mode reserved keyword." +- name: SETTER_FORMAL_PARAMS + id: 63 + message: "Setter must have exactly one formal parameter." -- name: NEWLINE_NOT_ALLOWED_IN_STRING - id: 265 - message: "Newline is not allowed in strings" +- name: SETTER_NO_RETURN_TYPE + id: 241 + message: "Setter must not have return type even if it is void." -- name: INVALID_DIGIT - id: 266 - message: "Invalid digit." +- name: SPECIAL_METHOD_CONSTRUCTOR + id: 149 + message: "Constructor can not be special method." -- name: PRIVATE_IDENTIFIER_NOT_CONSTRUCTOR - id: 267 - message: "Private identifier can not be constructor." +- name: SPECIAL_PREDEFINED_METHOD_CANNOT_BE_ASYNC + id: 220 + message: "The special predefined method '{}' cannot be asynchronous." -- name: PRIVATE_IDENTIFIER_STRING - id: 268 - message: "Private identifier name can not be string." +- name: SPECIAL_PREDEFINED_METHOD_SHOULD_HAVE_ONE_PARAM + id: 221 + message: "The special predefined method '{}' should have exactly one required parameter." -- name: PRIVATE_IDENTIFIER_NUMBER - id: 269 - message: "Private identifier name can not be number." +- name: SPECIAL_PREDEFINED_METHOD_SHOULD_HAVE_TWO_PARAMS + id: 222 + message: "The special predefined method '{}' should have exactly two required parameter." -- name: UNEXPECTED_CHAR_PRIVATE_IDENTIFIER - id: 270 - message: "Unexpected character in private identifier." +- name: SPECIAL_PREDEFINED_METHOD_SHOULD_NOT_HAVE_PARAMS + id: 223 + message: "The special predefined method '{}' should not have parameters." -- name: ESCAPE_SEQUENCES_IN_KEYWORD - id: 271 - message: "Escape sequences are not allowed in keyword." +- name: SPREAD_MUST_BE_LAST_IN_TUPLE + id: 136 + message: "Spread type must be at the last index in the tuple type." -- name: ONLY_CONSTANT_EXPRESSION - id: 272 - message: "Only constant expression is expected in the field" +- name: SPREAD_TYPE_MUST_BE_ARRAY + id: 139 + message: "Spread type must be an array type." -- name: DIVISION_BY_ZERO - id: 273 - message: "Division by zero is not allowed." +- name: STATIC_LATE_INITIALIZATION_FIELD_INVALID_MODIFIER + id: 303 + message: "Late-initialized field cannot be defined as static." -- name: UNSUPPORTED_OPERATOR_FOR_STRING - id: 274 - message: "Unsupported operator for String." +- name: STATIC_PROPERTY_PROTOTYPE + id: 155 + message: "Classes may not have static property named prototype." + +- name: STRICT_MODE_FUNC_DECL + id: 198 + message: "In strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement." - name: STRING_INTERPOLATION_NOT_CONSTANT id: 275 message: "String Interpolation Expression is not constant expression." -- name: ENUM_STRING_TYPE_ALL_ITEMS_INIT - id: 276 - message: "All items of string-type enumeration should be explicitly initialized." +- name: TAGGED_TEMPLATE_LITERALS_IN_OPTIONALCHAIN + id: 56 + message: "Tagged Template Literals are not allowed in optionalChain." -- name: UNEXPECTED_CHAR_ETSNOLINT - id: 277 - message: "Unexpected character for ETSNOLINT argument! [VALID ONLY: a-z, '-']." +- name: THIS_IN_NON_STATIC_METHOD + id: 44 + message: "A 'this' type is available only as return type in a non-static method of a class or struct and extension functions." -- name: INVALID_ARGUMENT_ETSNOLINT - id: 278 - message: "Invalid argument for ETSNOLINT!" +- name: TOO_LARGE_NUM + id: 262 + message: "Number is too large." -- name: CAN_NOT_FIND_NAME_TO_EXPORT - id: 279 - message: "Cannot find name '{}' to export." +- name: TRAILING_COMMA_NOT_ALLOWED + id: 150 + message: "Trailing comma is not allowed in this context." -- name: CAN_NOT_RENAME_ANNOTATION - id: 280 - message: "Can not rename annotation '{}' in export or import statements." +- name: TYPEOF_IN_ANNOTATION + id: 309 + message: "Result of 'typeof' operator is not supported to be used as type annotation." -- name: DUPLICATE_EXPORT_NAME - id: 281 - message: "The given name '{}' is already used in another export." +- name: TYPE_ALIAS_INVALID_NAME + id: 225 + message: "Type alias name cannot be '{}'." -- name: ALREADY_EXPORTED - id: 282 - message: "Cannot export '{}', it was already exported." +- name: TYPE_ALIAS_ONLY_TOP_LEVEL + id: 129 + message: "Type alias is allowed only as top-level declaration." -- name: NAME_CANNOT_BE_EXPORTED_AND_TYPE_EXPORTED - id: 283 - message: "Name '{}' cannot be exported and type exported at the same time." +- name: TYPE_ANNOTATION_FOR_CONSTRUCTOR + id: 140 + message: "Type annotation isn't allowed for constructor." + +- name: TYPE_EXPECTED + id: 188 + message: "Type expected." + +- name: TYPE_IMPORT_MISSING_SELECTIVE_BINDING + id: 110 + message: "Type import requires selective binding to define the required imported elements." + +- name: TYPE_PARAM_DEC_EXPECTED + id: 176 + message: "Type parameter declaration expected." -- name: CANNOT_EXPORT_SAME_TYPE_TWICE - id: 284 - message: "Cannot export the same '{}' type twice." +- name: TYPE_PARAM_LIST_EMPTY + id: 191 + message: "Type parameter list cannot be empty." -- name: DUPLICATE_PROTO_FIELDS - id: 285 - message: "Duplicate __proto__ fields are not allowed in object literals" +- name: UNDEFINED_LABEL + id: 162 + message: "Undefined label." -- name: INVALID_SHORTHAND_PROPERTY_INITIALIZER - id: 286 - message: "Invalid shorthand property initializer." +- name: UNEXPECTED_ARROWPARAM_ELEMENT + id: 148 + message: "Unexpected ArrowParameter element." -- name: RETURN_WITH_VALUE - id: 287 - message: "Unexpected return value." +- name: UNEXPECTED_CHAR_ETSNOLINT + id: 277 + message: "Unexpected character for ETSNOLINT argument! [VALID ONLY: a-z, '-']." -- name: INVALID_INIT_IN_PACKAGE - id: 288 - message: "Non-constant initializer of Package should be apply in Initializer Block." +- name: UNEXPECTED_CHAR_PRIVATE_IDENTIFIER + id: 270 + message: "Unexpected character in private identifier." -- name: PACKAGE_MULTIPLE_STATIC_BLOCK - id: 289 - message: "static block cannot apply to multi-files for one package" +- name: UNEXPECTED_DEFAULT + id: 235 + message: "Unexpected token 'default'. Only declarations are allowed after 'export default'." -- name: CONSTANT_MULTI_INITIALIZED_IN_STATIC_BLOCK - id: 290 - message: "package constant property initialization can only be applied once in static block" +- name: UNEXPECTED_ID + id: 45 + message: "Unexpected identifier." -- name: INVALID_PACKAGE_TOP_LEVEL_STMT - id: 291 - message: "Invalid package toplevel statement" +- name: UNEXPECTED_MODIFIER + id: 153 + message: "Unexpected modifier." -- name: ONLY_CONSTANT_ALLOWED - id: 292 - message: "Only constant expression is expected in the field" +- name: UNEXPECTED_PRIVATE + id: 47 + message: "Unexpected private identifier." -- name: ENUM_OR_ANNOTATION_DIVIDE_BY_ZERO - id: 293 - message: "Division by zero are not allowed in Enum or Annotation" +- name: UNEXPECTED_STRICT_MODE_RESERVED_KEYWORD + id: 264 + message: "Unexpected strict mode reserved keyword." -- name: MISSING_INIT_FOR_CONST_PACKAGE_PROP - id: 294 - message: "Missing initialization for const package property" +- name: UNEXPECTED_SUPER + id: 61 + message: "Unexpected super keyword." -- name: PREDEFINED_TYPE_AS_IDENTIFIER - id: 295 - message: "{} is a predefined type, cannot be used as an identifier" +- name: UNEXPECTED_THIS + id: 240 + message: "Unexpected 'this' keyword in non-receiver context." -- name: EXPORT_WITHOUT_DECLARE_IN_DECL_MODULE - id: 296 - message: "Export keyword without declare shouldn't be used in declaration module." +- name: UNEXPECTED_TOKEN + id: 16 + message: "Unexpected token." -- name: ERROR_ARKTS_NO_VAR - id: 297 - message: "'var' keyword is not supported. Use 'let' instead." +- name: UNEXPECTED_TOKEN_AS + id: 95 + message: "Unexpected token, expected 'as'." -- name: ERROR_ARKTS_NO_PRIVATE_IDENTIFIERS - id: 298 - message: "Use 'private' keyword to declare an identifier as private." +- name: UNEXPECTED_TOKEN_ENUM + id: 178 + message: "Unexpected token in enum member." -- name: ERROR_ARKTS_NO_DEBUGGER_STATEMENT - id: 299 - message: "Debugger statement is not supported!" +- name: UNEXPECTED_TOKEN_EXPECTED_BACKTICK_OR_DOLLAR_LBRACE + id: 259 + message: "Unexpected token, expected '${' or '`'" -- name: MISSING_LOOP_BODY - id: 300 - message: "Missing body in {} statement" +- name: UNEXPECTED_TOKEN_EXPECTED_PARAM + id: 228 + message: "Unexpected token, expected '{}'." -- name: MISSING_LOOP_CONDITION - id: 301 - message: "Missing condition in {} statement" +- name: UNEXPECTED_TOKEN_EXPECTED_PARAM_OR_PARAM + id: 229 + message: "Unexpected token, expected '{}' or '{}'." -- name: PRIVATE_FIELD_MISMATCH - id: 302 - message: "Private field '{}' must be declared in an enclosing class" +- name: UNEXPECTED_TOKEN_FOR_PARAM + id: 187 + message: "Unexpected '?' for parameter." -- name: STATIC_LATE_INITIALIZATION_FIELD_INVALID_MODIFIER - id: 303 - message: "Late-initialized field cannot be defined as static." +- name: UNEXPECTED_TOKEN_ID + id: 112 + message: "Unexpected token, expected an identifier." -- name: LATE_INITIALIZATION_FIELD_HAS_DEFAULT_VALUE - id: 304 - message: "Late-initialized field cannot have default value." +- name: UNEXPECTED_TOKEN_ID_FUN + id: 147 + message: "Unexpected token, expected function identifier." -- name: DEEP_NESTING - id: 305 - message: "Maximum allowed nesting level exceeded." +- name: UNEXPECTED_TOKEN_IN_PRIVATE + id: 160 + message: "Unexpected token in private field." -- name: OPTIONAL_VARIABLE - id: 306 - message: "Optional variable is deprecated and no longer supported." +- name: UNEXPECTED_TOKEN_PARAM + id: 227 + message: "Unexpected token '{}'." -- name: ERROR_ARKTS_NO_EXPORT_ASSIGNMENT - id: 307 - message: "'export = ...' syntax is not supported, use regular import/export instead!" +- name: UNEXPECTED_TOKEN_PARAM_EXPECTED_CASE_OR_DEFAULT + id: 231 + message: "Unexpected token '{}', expected 'case' or 'default'." -- name: ERROR_ARKTS_NO_AMBIENT_DECLS - id: 308 - message: "Ambient module declaration is not supported!" +- name: UNEXPECTED_TOKEN_PRIVATE_ID + id: 124 + message: "Unexpected token, expected 'private' or identifier." -- name: TYPEOF_IN_ANNOTATION - id: 309 - message: "Result of 'typeof' operator is not supported to be used as type annotation." +- name: UNEXPECTED_TOKEN_STRING_LITERAL + id: 151 + message: "Unexpected token, expected string literal." -- name: WRONG_LEFT_OF_INSTANCEOF - id: 310 - message: "The left operand of 'instanceof' operator cannot be a type." +- name: UNEXPECTED_TOKEN_WHILE + id: 170 + message: "Unexpected token, expected 'while'." -- name: AS_CONST_USAGE - id: 311 - message: "'as const' assertion is not supported." +- name: UNHANDLED_THROW_IN_INITIALIZER + id: 243 + message: "Unhandled throw statement." -- name: ERROR_ARKTS_NO_REQUIRE - id: 312 - message: "Importing by 'require' and 'import' assignment is not supported, use 'import * as ... from ...' form instead!" +- name: UNSUPPORTED_CHAR_LIT + id: 261 + message: "Unsupported character literal." -- name: ERROR_ARKTS_NO_IMPORT_ASSERTIONS - id: 313 - message: "Import assertion is not supported, please use the ordinary import syntax instead!" +- name: UNSUPPORTED_ENUM_TYPE + id: 327 + message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal + types, not annotations." -- name: GENERATOR_FUNCTION - id: 314 - message: "Generator functions are not supported, please use async/await mechanism for multitasking" +- name: UNSUPPORTED_OPERATOR_FOR_STRING + id: 274 + message: "Unsupported operator for String." -- name: LITERAL_VALUE_IDENT - id: 315 - message: "Number, string or computed value property name '{}' is not allowed, use classes to access data by property names that are identifiers" +- name: UNTERMINATED_MULTI_LINE_COMMENT + id: 245 + message: "Unterminated multi-line comment." -- name: HARD_KEYWORD_IDENT - id: 316 - message: "Hard keyword '{}' cannot be used as identifier" +- name: UNTERMINATED_REGEX + id: 260 + message: "Unterminated RegExp." -- name: NOT_AS_OBJECT - id: 318 - message: "{} cannot be used as object." +- name: UNTERMINATED_STRING + id: 253 + message: "Unterminated string." -- name: FIELD_IN_PARAM - id: 319 - message: "Declaring fields in parameter list is not supported" +- name: UNTERMINATED_UNICODE_PROP_ESCAPE + id: 86 + message: "Unterminated Unicode property escape." -- name: FUNC_EXPR - id: 320 - message: "Function expressions are not supported, use arrow functions instead" +- name: USING_RESERVED_NAME_AS_VARIABLE_OR_TYPE_NAME + id: 242 + message: "'{}' is reserved and cannot be used as a variable/type name" -- name: ONLY_STRING_LITERAL_IN_INIT_MODULE - id: 321 - message: "initModule() only accept string literal as argument." +- name: VALUE_IS_NOT_SET + id: 128 + message: "You didn't set the value." -- name: INIT_MODULE_DECLARATION_POSITION - id: 322 - message: "initModule() must only be called immediately after the import statement, and before any other declarations or statements." +- name: VARIANCE_NOD_ALLOWED + id: 98 + message: "Variance modifier is not allowed here." -- name: OVERLOAD_MODIFIERS - id: 323 - message: "Overload Declaration only allow use modifier 'static' | 'async'." +- name: VAR_DEC_EXPECTED + id: 126 + message: "Variable declaration expected." -- name: CLASS_INTERFACE_METHOD_OVERLOADED_NAME_MUST_IDENT - id: 324 - message: "The overloaded method name in class/interface method overload declaration must be identifier." +- name: WITH_DEPRECATED + id: 161 + message: "'With' is deprecated and not supported any more." -- name: FUNCTION_OVERLOADED_NAME_MUST_QUALIFIED_NAME - id: 325 - message: "The overloaded method name in function overload declaration must be qualified name." +- name: WRONG_LEFT_OF_INSTANCEOF + id: 310 + message: "The left operand of 'instanceof' operator cannot be a type." -- name: MORE_INDEXER - id: 326 - message: "Only one index signature can exist in a class" +- name: YIELD_IN_ARROW_FUN_PARAM + id: 66 + message: "yield is not allowed in arrow function parameters." -- name: UNSUPPORTED_ENUM_TYPE - id: 327 - message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations." +- name: YIELD_IN_GENERATOR_PARAM + id: 54 + message: "Yield is not allowed in generator parameters." + +graveyard: +- 317 +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. diff --git a/ets2panda/util/diagnostic/warning.yaml b/ets2panda/util/diagnostic/warning.yaml index e8164fa885..71701fcf70 100644 --- a/ets2panda/util/diagnostic/warning.yaml +++ b/ets2panda/util/diagnostic/warning.yaml @@ -12,98 +12,107 @@ # limitations under the License. warning: -- name: SUGGEST_FINAL_MODIFIER_FOR_CLASS - id: 1 - message: "Suggest 'final' modifier for class." -- name: SUGGEST_FINAL_MODIFIER_FOR_METHOD - id: 2 - message: "Suggest 'final' modifier for method." +- name: ANNOTATION_UNUSED_GENERIC_ALIAS_WARN + id: 9 + message: "Type alias generic parameter '{}' is not used in type annotation" -- name: PROHIBIT_TOP_LEVEL_STATEMENTS - id: 3 - message: "Prohibit top-level statements." +- name: ASSIGN_TO_READONLY + id: 16 + message: "Cannot assign to '{}' because it is a read-only property." - name: BOOST_EQUALITY_STATEMENT id: 4 message: "Boost Equality Statement. Change sides of binary expression." -- name: REPLACE_ASYNC_FUNCTION_WITH_COROUTINE - id: 5 - message: "Replace asynchronous function with coroutine." +- name: DUPLICATE_SIGS + id: 12 + message: "Detect duplicate signatures, use '{}{}' to replace" -- name: REPLACE_LAMBDA_FUNCTION_WITH_REGULAR_FUNCTION - id: 6 - message: "Replace the lambda function with a regular function." +- name: EXTENSION_MISMATCH + id: 25 + message: "Not matching extensions! Sourcefile: {}, Manual(used): {}" + +- name: EXTENSION_NONPUBLIC_COLLISION + id: 13 + message: "The extension function '{}' has the same name with non-public method in class {}" + +- name: FINALLY_CANT_COMPLETE + id: 21 + message: "Finally clause cannot complete normally" + +- name: FUNCTION_ASM_SIG_COLLISION + id: 22 + message: "Function {} with this assembly signature already declared." + +- name: GETTER_LOOP + id: 23 + message: "Reading the value of the property inside its getter may lead to an endless loop." - name: IMPLICIT_BOXING_TO id: 7 message: "Implicit Boxing to {}{}." -- name : IMPLICIT_UNBOXING_TO +- name: IMPLICIT_UNBOXING_TO id: 8 message: "Implicit Unboxing to {}{}." -- name : ANNOTATION_UNUSED_GENERIC_ALIAS_WARN - id: 9 - message: "Type alias generic parameter '{}' is not used in type annotation" - -- name: NO_OHMURL - id: 11 - message: "'ohmUrl' for module '{}' wasn't specified" - -- name: DUPLICATE_SIGS - id: 12 - message: "Detect duplicate signatures, use '{}{}' to replace" - -- name: EXTENSION_NONPUBLIC_COLLISION - id: 13 - message: "The extension function '{}' has the same name with non-public method in class {}" - -- name: NULLISH_OPERAND - id: 14 - message: "Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'." +- name: IMPROPER_NUMERIC_CAST + id: 29 + message: "'As' expression for cast is deprecated for numeric types. Use explicit conversion function {}.to{}(...) instead." - name: INSTANCEOF_ERASED id: 15 message: "Type parameter is erased from type '{}' when used in instanceof expression." -- name: ASSIGN_TO_READONLY - id: 16 - message: "Cannot assign to '{}' because it is a read-only property." +- name: MAYBE_FALLTHROUGH + id: 20 + message: "Possible fall-through into case" - name: MAYBE_REASSIGNED id: 17 message: "{} '{}' might already have been assigned." -- name: MAYBE_FALLTHROUGH - id: 20 - message: "Possible fall-through into case" +- name: NO_OHMURL + id: 11 + message: "'ohmUrl' for module '{}' wasn't specified" -- name: FINALLY_CANT_COMPLETE - id: 21 - message: "Finally clause cannot complete normally" +- name: NULLISH_OPERAND + id: 14 + message: "Bad operand type, the operand of the non-nullish expression is 'null' or 'undefined'." -- name: FUNCTION_ASM_SIG_COLLISION - id: 22 - message: "Function {} with this assembly signature already declared." +- name: PROHIBIT_TOP_LEVEL_STATEMENTS + id: 3 + message: "Prohibit top-level statements." -- name: GETTER_LOOP - id: 23 - message: "Reading the value of the property inside its getter may lead to an endless loop." +- name: REPLACE_ASYNC_FUNCTION_WITH_COROUTINE + id: 5 + message: "Replace asynchronous function with coroutine." + +- name: REPLACE_LAMBDA_FUNCTION_WITH_REGULAR_FUNCTION + id: 6 + message: "Replace the lambda function with a regular function." - name: SETTER_LOOP id: 24 message: "Assigning new value to the property inside its setter may lead to an endless loop." -- name: EXTENSION_MISMATCH - id: 25 - message: "Not matching extensions! Sourcefile: {}, Manual(used): {}" +- name: SUGGEST_FINAL_MODIFIER_FOR_CLASS + id: 1 + message: "Suggest 'final' modifier for class." + +- name: SUGGEST_FINAL_MODIFIER_FOR_METHOD + id: 2 + message: "Suggest 'final' modifier for method." - name: UNREACHABLE_STMT id: 26 message: "Unreachable statement." -- name: IMPROPER_NUMERIC_CAST - id: 29 - message: "'As' expression for cast is deprecated for numeric types. Use explicit conversion function {}.to{}(...) instead." +graveyard: +- 10 +- 18 +- 19 +- 27 +- 28 +# See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. -- Gitee From 636b4f960ed1d546b8b6a3ed50424ffcec68a4a7 Mon Sep 17 00:00:00 2001 From: daizihan Date: Mon, 7 Jul 2025 21:46:15 +0800 Subject: [PATCH 057/107] Fix fuzz crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKLXR?from=project-issue Signed-off-by: daizihan --- ets2panda/checker/ets/utilityTypeHandlers.cpp | 3 +++ .../test/ast/compiler/ets/fuzzingtest6.ets | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/fuzzingtest6.ets diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 0224e9882e..107f18115f 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -886,6 +886,9 @@ Type *ETSChecker::CreatePartialTypeClassDef(ir::ClassDefinition *const partialCl LogError(diagnostic::CYCLIC_CLASS_SUPER_TYPE, {}, classDef->Start()); return partialType; } + if (partialSuper->IsTypeError()) { + return partialType; + } partialType->SetSuperType(partialSuper->AsETSObjectType()); } diff --git a/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets b/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets new file mode 100644 index 0000000000..79c7af6977 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzzingtest6.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +interface inter { } + +class B extends A implements inter { +} + +function foo1(b: Partial>) { +} + +/* @@? 18:20 Error TypeError: Cannot find type 'A'. */ +/* @@? 18:20 Error TypeError: The super type of 'B' class is not extensible. */ -- Gitee From 389ccfaeb12e521394eb0c30f9e8864937e68335 Mon Sep 17 00:00:00 2001 From: Peter Pronai Date: Fri, 23 May 2025 11:20:55 +0000 Subject: [PATCH 058/107] TS type assertion errors and diagnostics undo Adds a mechanism for undoing log entries in the diagnostic engine. This is useful when there are multiple parse attempts, like in this case. This way the generic arrow function parser and the assertion parser are both free to emit any diagnostics and their caller can choose which ones to keep. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICA4XY Testing: ast, astchecker, parser Fixes #24577 internal issue. Change-Id: I7679f1d96db189cfb1ab31b256f62919cedcc521 Signed-off-by: Peter Pronai --- ets2panda/parser/ETSparserExpressions.cpp | 25 +++++++++++------ ets2panda/parser/TypedParser.cpp | 3 +++ .../ast/parser/ets/generic_lambda_err3.ets | 24 ++++++++++++----- .../test/ast/parser/ets/ts-type-assertion.ets | 27 +++++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 4 +++ 5 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/ts-type-assertion.ets diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 7cd587f214..0d42a56fbb 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -779,21 +779,30 @@ ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags) if (Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_AT)) { annotations = ParseAnnotations(false); } - auto savedPos = Lexer()->GetToken().Start(); + const auto savedPosition = Lexer()->Save(); + const auto start = Lexer()->GetToken().Start(); if (Lexer()->GetToken().Type() == lexer::TokenType::KEYW_YIELD && (flags & ExpressionParseFlags::DISALLOW_YIELD) == 0U) { ir::YieldExpression *yieldExpr = ParseYieldExpression(); return ParsePotentialExpressionSequence(yieldExpr, flags); } - if (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_LESS_THAN) { - ir::Expression *expr = ParseGenericArrowFunction(true); - if (expr == nullptr) { - return AllocBrokenExpression(Lexer()->GetToken().Loc()); + const auto arrowStart = DiagnosticEngine().Save(); + if (ir::Expression *expr = ParseGenericArrowFunction(true); expr != nullptr && !expr->IsBrokenExpression()) { + return expr; } - - return expr; + const auto afterArrow = DiagnosticEngine().Save(); + Lexer()->Rewind(savedPosition); + if (const ir::Expression *typeAssertion = ParseTypeAssertion(); typeAssertion != nullptr) { + DiagnosticEngine().UndoRange(arrowStart, afterArrow); + LogError(diagnostic::TS_TYPE_ASSERTION, util::DiagnosticMessageParams {}, start); + ES2PANDA_ASSERT(DiagnosticEngine().IsAnyError()); + return AllocBrokenExpression(typeAssertion->Range()); + } + DiagnosticEngine().Rollback(afterArrow); + ES2PANDA_ASSERT(DiagnosticEngine().IsAnyError()); + return AllocBrokenExpression(lexer::SourceRange {start, Lexer()->GetToken().End()}); } ir::Expression *unaryExpressionNode = ParseUnaryOrPrefixUpdateExpression(flags); @@ -802,7 +811,7 @@ ir::Expression *ETSParser::ParseExpression(ExpressionParseFlags flags) } ir::Expression *assignmentExpression = ParseAssignmentExpression(unaryExpressionNode, flags); - ApplyAnnotationsToNode(assignmentExpression, std::move(annotations), savedPos); + ApplyAnnotationsToNode(assignmentExpression, std::move(annotations), start); if (Lexer()->GetToken().NewLine()) { return assignmentExpression; diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index cc626c2ed9..d9a11d33c7 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -196,6 +196,9 @@ ir::TSTypeAssertion *TypedParser::ParseTypeAssertion() Lexer()->NextToken(); // eat '>' ir::Expression *expression = ParseExpression(); + if (expression == nullptr || expression->IsBrokenExpression()) { + return nullptr; + } auto *typeAssertion = AllocNode(typeAnnotation, expression); ES2PANDA_ASSERT(typeAssertion != nullptr); typeAssertion->SetRange({start, Lexer()->GetToken().End()}); diff --git a/ets2panda/test/ast/parser/ets/generic_lambda_err3.ets b/ets2panda/test/ast/parser/ets/generic_lambda_err3.ets index 533f3f5761..b6a314cde3 100644 --- a/ets2panda/test/ast/parser/ets/generic_lambda_err3.ets +++ b/ets2panda/test/ast/parser/ets/generic_lambda_err3.ets @@ -13,14 +13,26 @@ * limitations under the License. */ + let foo1 = let foo2 = () +let foo3 = ; +let foo4 = (); function main() { - let foo3 = - let foo4 = () + let foo5 = + let foo6 = () } -/* @@? 17:1 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 18:1 Error SyntaxError: Unexpected token, expected '=>'. */ -/* @@? 20:5 Error SyntaxError: Unexpected token, expected '('. */ -/* @@? 21:1 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 18:1 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 18:5 Error SyntaxError: Unexpected token 'foo2'. */ +/* @@? 18:5 Error TypeError: Unresolved reference foo2 */ +/* @@? 19:1 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 19:5 Error SyntaxError: Unexpected token 'foo3'. */ +/* @@? 19:5 Error TypeError: Unresolved reference foo3 */ +/* @@? 19:15 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 20:17 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 23:5 Error SyntaxError: Unexpected token, expected '('. */ +/* @@? 23:9 Error SyntaxError: Unexpected token 'foo6'. */ +/* @@? 23:9 Error TypeError: Unresolved reference foo6 */ +/* @@? 24:1 Error SyntaxError: Unexpected token, expected '=>'. */ +/* @@? 39:1 Error SyntaxError: Expected '}', got 'end of stream'. */ diff --git a/ets2panda/test/ast/parser/ets/ts-type-assertion.ets b/ets2panda/test/ast/parser/ets/ts-type-assertion.ets new file mode 100644 index 0000000000..a54c5d887a --- /dev/null +++ b/ets2panda/test/ast/parser/ets/ts-type-assertion.ets @@ -0,0 +1,27 @@ +/* + * 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. + */ + +const a = 1; +type t = number; +const b = a; +const c = foo; +const d = (foo); +const e = (foo); +const f = foo; +/* @@? 18:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 19:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 20:12 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 21:11 Error SyntaxError: Type cast syntax '' is not supported, please use 'as' keyword instead */ +/* @@? 22:14 Error SyntaxError: Unexpected token, expected '('. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 47d782ae57..4bb897e9f3 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1121,6 +1121,10 @@ syntax: id: 150 message: "Trailing comma is not allowed in this context." +- name: TS_TYPE_ASSERTION + id: 178094 + message: "Type cast syntax '' is not supported, please use 'as' keyword instead" + - name: TYPEOF_IN_ANNOTATION id: 309 message: "Result of 'typeof' operator is not supported to be used as type annotation." -- Gitee From 386bb9e03b606a6685e6b7894f47cb8ddf90fc38 Mon Sep 17 00:00:00 2001 From: ZhongNing Date: Mon, 7 Jul 2025 15:24:31 +0800 Subject: [PATCH 059/107] fix arkts-method-inherit-rule Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKE8R Test scenarios: fix bug Signed-off-by: ZhongNing --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 54 ++++++++++++++++--- .../linter/test/main/method_inheritance.ets | 11 ++++ 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..b309b41483 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -3477,6 +3477,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { // Check if every type in baseType is also present in derivedType for (const typeStr of baseTypeSet) { if (!derivedTypeSet.has(typeStr)) { + if (TypeScriptLinter.areWrapperAndPrimitiveTypesEqual(typeStr, derivedTypeSet)) { + continue; + } return false; } } @@ -3494,10 +3497,30 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { // All types in `fromTypes` should exist in `toTypes` for assignability. return fromTypes.every((typeStr) => { - return toTypes.has(typeStr); + if (toTypes.has(typeStr)) { + return true; + } + return TypeScriptLinter.areWrapperAndPrimitiveTypesEqual(typeStr, toTypes); }); } + // Check if a type string has an equivalent primitive/wrapper type in a set + private static areWrapperAndPrimitiveTypesEqual(typeStr: string, typeSet: Set): boolean { + const typePairs = [ + ['String', 'string'], + ['Number', 'number'], + ['Boolean', 'boolean'] + ]; + + for (const [wrapper, primitive] of typePairs) { + if ((typeStr === wrapper && typeSet.has(primitive)) || + (typeStr === primitive && typeSet.has(wrapper))) { + return true; + } + } + return false; + } + private isDerivedTypeAssignable(derivedType: ts.Type, baseType: ts.Type): boolean { const baseSymbol = baseType.getSymbol(); const derivedSymbol = derivedType.getSymbol(); @@ -3529,12 +3552,29 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { // Converts union types into an array of type strings for easy comparison. private flattenUnionTypes(type: ts.Type): string[] { - if (type.isUnion()) { - return type.types.map((t) => { - return this.tsTypeChecker.typeToString(t); - }); - } - return [this.tsTypeChecker.typeToString(type)]; + if (type.isUnion()) { + return type.types.map((t) => { + return TypeScriptLinter.normalizeTypeString(this.tsTypeChecker.typeToString(t)); + }); + } + return [TypeScriptLinter.normalizeTypeString(this.tsTypeChecker.typeToString(type))]; + } + + // Normalize type string to handle primitive wrapper types consistently + private static normalizeTypeString(typeStr: string): string { + // Handle all primitive wrapper types + const wrapperToPrimitive: Record = { + 'String': 'string', + 'Number': 'number', + 'Boolean': 'boolean' + }; + + // Replace wrapper types with their primitive counterparts + let normalized = typeStr; + for (const [wrapper, primitive] of Object.entries(wrapperToPrimitive)) { + normalized = normalized.replace(new RegExp(wrapper, 'g'), primitive); + } + return normalized; } private checkClassImplementsMethod(classDecl: ts.ClassDeclaration, methodName: string): boolean { diff --git a/ets2panda/linter/test/main/method_inheritance.ets b/ets2panda/linter/test/main/method_inheritance.ets index 12c5ac3f16..fe85d554a3 100644 --- a/ets2panda/linter/test/main/method_inheritance.ets +++ b/ets2panda/linter/test/main/method_inheritance.ets @@ -359,5 +359,16 @@ class BBB2 extends AAA { class BBB3 extends AAA { test() { //error + } +} + + +abstract class Test1 { + abstract test(params: Map): void; +} + +class Test2 extends Test1 { + test(params: Map): void { // no Error + } } \ No newline at end of file -- Gitee From fe434f901e5c4f49ee94b55454bb32624fb571f7 Mon Sep 17 00:00:00 2001 From: ekkoruse Date: Sat, 5 Jul 2025 17:13:10 +0800 Subject: [PATCH 060/107] log syntax error for default value in declare Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK7TT?from=project-issue Signed-off-by: ekkoruse --- .../ets/defaultParametersLowering.cpp | 13 +++++++++++- .../compiler/ets/default_param_declare.ets | 21 +++++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 4 ++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/compiler/ets/default_param_declare.ets diff --git a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp index dd3fe91cd7..901046c077 100644 --- a/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp +++ b/ets2panda/compiler/lowering/ets/defaultParametersLowering.cpp @@ -42,6 +42,17 @@ static void TransformDefaultParameters(public_lib::Context *ctx, ir::ScriptFunct const std::vector ¶ms, bool isInterfaceFunction) { + auto validateDefaultParamInDeclare = [ctx, function, ¶ms]() { + for (auto param : params) { + if (param->Initializer() == nullptr) { + continue; + } + param->SetInitializer(nullptr); + if ((function->Flags() & ir::ScriptFunctionFlags::EXTERNAL) != 0U) { + ctx->GetChecker()->AsETSChecker()->LogError(diagnostic::DEFAULT_PARAM_IN_DECLARE, param->Start()); + } + } + }; if (isInterfaceFunction) { for (const auto param : params) { TransformInitializer(ctx->allocator, ctx->parser->AsETSParser(), param); @@ -50,7 +61,7 @@ static void TransformDefaultParameters(public_lib::Context *ctx, ir::ScriptFunct } if (!function->HasBody()) { // #23134 - ES2PANDA_ASSERT(ctx->diagnosticEngine->IsAnyError()); + validateDefaultParamInDeclare(); return; } diff --git a/ets2panda/test/ast/compiler/ets/default_param_declare.ets b/ets2panda/test/ast/compiler/ets/default_param_declare.ets new file mode 100644 index 0000000000..491faa15e8 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/default_param_declare.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + +declare class A{ + foo(/* @@ label1 */a:number = 1, /* @@ label2 */b:int = 2):void +} + +/* @@@ label1 Error SyntaxError: A parameter initializer is only allowed in a function or constructor implementation. */ +/* @@@ label2 Error SyntaxError: A parameter initializer is only allowed in a function or constructor implementation. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 47d782ae57..6d8a0c31f7 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -169,6 +169,10 @@ syntax: id: 133 message: "Default value is allowed only for optional parameters." +- name: DEFAULT_PARAM_IN_DECLARE + id: 328 + message: "A parameter initializer is only allowed in a function or constructor implementation." + - name: DEFAULT_UNDEF_NOT_ALLOWED id: 132 message: "Not enable default value with default undefined." -- Gitee From d4e064497b897e92843119c0d9346afa57327de2 Mon Sep 17 00:00:00 2001 From: gcw_HJ4zMsdn Date: Tue, 8 Jul 2025 12:11:12 +0800 Subject: [PATCH 061/107] 0328-fix-alert Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKQW6 Signed-off-by: yp9522 --- ets2panda/checker/ETSAnalyzerHelpers.cpp | 1 + ets2panda/checker/TSAnalyzer.cpp | 11 ++- ets2panda/checker/ets/aliveAnalyzer.cpp | 1 + ets2panda/checker/ets/assignAnalyzer.cpp | 1 + ets2panda/checker/ets/dynamic.cpp | 1 + ets2panda/checker/ets/etsWarningAnalyzer.cpp | 7 +- ets2panda/checker/ets/function.cpp | 11 ++- ets2panda/checker/ets/helpers.cpp | 22 +++-- ets2panda/checker/ets/object.cpp | 20 ++-- ets2panda/checker/ets/typeCheckingHelpers.cpp | 7 +- ets2panda/checker/ets/typeCreation.cpp | 2 + ets2panda/checker/ets/typeRelationContext.h | 2 + ets2panda/checker/ets/utilityTypeHandlers.cpp | 16 ++- ets2panda/checker/ts/destructuringContext.cpp | 4 +- ets2panda/checker/ts/function.cpp | 10 +- ets2panda/checker/ts/object.cpp | 2 + .../checker/types/ets/etsFunctionType.cpp | 4 +- ets2panda/checker/types/ets/etsObjectType.cpp | 1 + ets2panda/checker/types/signature.cpp | 3 +- .../checker/types/ts/objectDescriptor.cpp | 2 +- ets2panda/parser/ASparser.cpp | 4 + ets2panda/parser/ETSparser.cpp | 5 +- ets2panda/parser/ETSparserAnnotations.cpp | 2 + ets2panda/parser/ETSparserClasses.cpp | 3 + ets2panda/parser/ETSparserExpressions.cpp | 2 + ets2panda/parser/TSparser.cpp | 3 +- ets2panda/parser/TypedParser.cpp | 4 +- .../parser/context/classPrivateContext.cpp | 4 +- ets2panda/parser/expressionParser.cpp | 97 ++++++++++--------- ets2panda/parser/expressionTSParser.cpp | 12 ++- ets2panda/parser/parserImpl.cpp | 30 +++--- ets2panda/parser/program/program.cpp | 2 +- ets2panda/parser/statementParser.cpp | 84 ++++++++-------- ets2panda/parser/statementTSParser.cpp | 12 +-- 34 files changed, 238 insertions(+), 154 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 9e04b6d31d..295eaa49b5 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -660,6 +660,7 @@ checker::Type *InferReturnType(ETSChecker *checker, ir::ScriptFunction *containi // First (or single) return statement in the function: auto *funcReturnType = stArgument == nullptr ? checker->GlobalVoidType() : checker->GetNonConstantType(stArgument->Check(checker)); + ES2PANDA_ASSERT(funcReturnType != nullptr); if (funcReturnType->IsTypeError()) { containingFunc->Signature()->RemoveSignatureFlag(checker::SignatureFlags::NEED_RETURN_TYPE); return funcReturnType; diff --git a/ets2panda/checker/TSAnalyzer.cpp b/ets2panda/checker/TSAnalyzer.cpp index c353155e2c..44d5a3d824 100644 --- a/ets2panda/checker/TSAnalyzer.cpp +++ b/ets2panda/checker/TSAnalyzer.cpp @@ -74,6 +74,7 @@ checker::Type *TSAnalyzer::Check(ir::TSIndexSignature *node) const checker::ObjectDescriptor *desc = checker->Allocator()->New(checker->Allocator()); checker::ObjectType *placeholder = checker->Allocator()->New(desc); + ES2PANDA_ASSERT(placeholder != nullptr); if (node->Kind() == ir::TSIndexSignature::TSIndexSignatureKind::NUMBER) { placeholder->Desc()->numberIndexInfo = info; } else { @@ -281,12 +282,13 @@ checker::Type *TSAnalyzer::Check(ir::ArrayExpression *expr) const util::StringView memberIndex = util::Helpers::ToStringView(checker->Allocator(), index); varbinder::LocalVariable *tupleMember = varbinder::Scope::CreateVar( checker->Allocator(), memberIndex, varbinder::VariableFlags::PROPERTY, nullptr); - + ES2PANDA_ASSERT(tupleMember != nullptr); if (inConstContext) { tupleMember->AddFlag(varbinder::VariableFlags::READONLY); } tupleMember->SetTsType(*it); + ES2PANDA_ASSERT(desc != nullptr); desc->properties.push_back(tupleMember); } @@ -327,7 +329,7 @@ checker::Type *TSAnalyzer::Check(ir::ArrowFunctionExpression *expr) const if (funcVar != nullptr && funcVar->TsType() == nullptr) { funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(checker->HandleFunctionReturn(expr->Function())); if (!expr->Function()->Body()->IsExpression()) { @@ -570,7 +572,7 @@ checker::Type *TSAnalyzer::Check(ir::FunctionExpression *expr) const if (funcVar != nullptr && funcVar->TsType() == nullptr) { funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(signature != nullptr); signature->SetReturnType(checker->HandleFunctionReturn(expr->Function())); expr->Function()->Body()->Check(checker); @@ -878,6 +880,7 @@ checker::Type *TSAnalyzer::Check(ir::ObjectExpression *expr) const } checker::Type *returnType = checker->Allocator()->New(desc); + ES2PANDA_ASSERT(returnType != nullptr); returnType->AsObjectType()->AddObjectFlag(checker::ObjectFlags::RESOLVED_MEMBERS | checker::ObjectFlags::CHECK_EXCESS_PROPS); return returnType; @@ -1850,6 +1853,7 @@ checker::Type *TSAnalyzer::Check(ir::TSEnumDeclaration *st) const if (enumVar->TsType() == nullptr) { checker::ScopeContext scopeCtx(checker, st->Scope()); checker::Type *enumType = InferType(checker, st->IsConst(), st); + ES2PANDA_ASSERT(enumType != nullptr); enumType->SetVariable(enumVar); enumVar->SetTsType(enumType); } @@ -1957,6 +1961,7 @@ checker::Type *TSAnalyzer::Check(ir::TSInterfaceDeclaration *st) const checker->Allocator()->New(checker->Allocator()); resolvedType = checker->Allocator()->New(checker->Allocator(), st->Id()->Name(), desc); + ES2PANDA_ASSERT(resolvedType != nullptr); resolvedType->SetVariable(var); var->SetTsType(resolvedType); } diff --git a/ets2panda/checker/ets/aliveAnalyzer.cpp b/ets2panda/checker/ets/aliveAnalyzer.cpp index 7ac350c66e..13abe6b9ca 100644 --- a/ets2panda/checker/ets/aliveAnalyzer.cpp +++ b/ets2panda/checker/ets/aliveAnalyzer.cpp @@ -256,6 +256,7 @@ void AliveAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) } if (status_ == LivenessStatus::ALIVE && !isVoid && !isPromiseVoid) { + ES2PANDA_ASSERT(methodDef->Function() != nullptr); if (!methodDef->Function()->HasReturnStatement()) { if (!util::Helpers::IsAsyncMethod(methodDef)) { checker_->LogError(diagnostic::MISSING_RETURN_STMT, {}, func->Start()); diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 1bf641755b..8d32f667b6 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -532,6 +532,7 @@ static bool IsInitialConstructor(const ir::AstNode *node) } const auto methodDef = node->AsMethodDefinition(); + ES2PANDA_ASSERT(methodDef != nullptr); if (methodDef->Function()->Body() == nullptr || methodDef->Function()->IsExternal()) { return false; } diff --git a/ets2panda/checker/ets/dynamic.cpp b/ets2panda/checker/ets/dynamic.cpp index a7622ce25b..2a67acd88d 100644 --- a/ets2panda/checker/ets/dynamic.cpp +++ b/ets2panda/checker/ets/dynamic.cpp @@ -63,6 +63,7 @@ void ProcessCheckerNode(ETSChecker *checker, ir::AstNode *node) // however right now checker do it when called on ClassDefinition auto method = node->AsMethodDefinition(); auto func = method->Value()->AsFunctionExpression()->Function(); + ES2PANDA_ASSERT(method->Id() != nullptr); func->Id()->SetVariable(method->Id()->Variable()); } ScopeContext checkerScope(checker, scope); diff --git a/ets2panda/checker/ets/etsWarningAnalyzer.cpp b/ets2panda/checker/ets/etsWarningAnalyzer.cpp index 20f01dae13..f686ff057b 100644 --- a/ets2panda/checker/ets/etsWarningAnalyzer.cpp +++ b/ets2panda/checker/ets/etsWarningAnalyzer.cpp @@ -101,8 +101,9 @@ void ETSWarningAnalyzer::AnalyzeClassMethodForFinalModifier(const ir::MethodDefi if (!potentialDescendant->IsDescendantOf(classAsETSObject)) { continue; } - const util::StringView bodyMethodName = - ETSChecker::GetSignatureFromMethodDefinition(bodyPart->AsMethodDefinition())->Function()->Id()->Name(); + auto signature = ETSChecker::GetSignatureFromMethodDefinition(bodyPart->AsMethodDefinition()); + ES2PANDA_ASSERT(signature != nullptr); + const util::StringView bodyMethodName = signature->Function()->Id()->Name(); const auto *func = methodDef->Function(); ES2PANDA_ASSERT(func != nullptr); if (bodyPart->IsOverride() && bodyMethodName != compiler::Signatures::CTOR && @@ -210,7 +211,7 @@ void ETSWarningAnalyzer::ETSWarningsProhibitTopLevelStatements(const ir::AstNode } for (const auto *itBody : classDef->Body()) { - if (!itBody->IsMethodDefinition() || + if (!itBody->IsMethodDefinition() || itBody->AsMethodDefinition()->Id() == nullptr || itBody->AsMethodDefinition()->Id()->Name() != compiler::Signatures::INIT_METHOD) { continue; } diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index a9a099ad1c..5c22183d03 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1093,6 +1093,7 @@ void ETSChecker::CollectSuitableSignaturesForTypeInference( for (auto *sig : signatures) { auto *sigParamType = GetNonNullishType(sig->Params().at(paramIdx)->TsType()); + ES2PANDA_ASSERT(sigParamType != nullptr); if (!sigParamType->IsETSFunctionType()) { continue; } @@ -1409,7 +1410,8 @@ static bool CollectOverload(checker::ETSChecker *checker, ir::MethodDefinition * for (ir::MethodDefinition *const currentFunc : method->Overloads()) { ldInfo.isDeclare &= currentFunc->IsDeclare(); - + ES2PANDA_ASSERT(currentFunc->Function() != nullptr); + ES2PANDA_ASSERT(currentFunc->Id() != nullptr); currentFunc->Function()->Id()->SetVariable(currentFunc->Id()->Variable()); checker->BuildFunctionSignature(currentFunc->Function(), method->IsConstructor()); if (currentFunc->Function()->Signature() == nullptr) { @@ -1461,10 +1463,11 @@ checker::Type *ETSChecker::BuildMethodSignature(ir::MethodDefinition *method) return method->TsType()->AsETSFunctionType(); } auto *methodId = method->Id(); + ES2PANDA_ASSERT(methodId != nullptr); + ES2PANDA_ASSERT(method->Function() != nullptr); method->Function()->Id()->SetVariable(methodId->Variable()); BuildFunctionSignature(method->Function(), method->IsConstructor()); if (method->Function()->Signature() == nullptr) { - ES2PANDA_ASSERT(methodId != nullptr); return methodId->Variable()->SetTsType(GlobalTypeError()); } auto *funcType = BuildMethodType(method->Function()); @@ -1972,6 +1975,7 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) void ETSChecker::CheckOverride(Signature *signature) { + ES2PANDA_ASSERT(signature != nullptr); auto *owner = signature->Owner(); ES2PANDA_ASSERT(owner != nullptr); bool isOverriding = false; @@ -2221,6 +2225,7 @@ ir::MethodDefinition *ETSChecker::CreateMethod(const util::StringView &name, ir: // CC-OFFNXT(G.FMT.05-CPP) project codestyle clang format off body, ir::FunctionSignature(nullptr, std::move(params), returnType), flags, modifiers}); // clang-format on + ES2PANDA_ASSERT(func != nullptr); func->SetScope(scope); func->SetIdent(nameId); if (body != nullptr && body->IsBlockStatement()) { @@ -2414,10 +2419,12 @@ ArenaVector ETSChecker::ExtendArgumentsWithFakeLamda(ir::CallE ProgramAllocator(), ir::ScriptFunction::ScriptFunctionData {body, ir::FunctionSignature(nullptr, std::move(params), nullptr), ir::ScriptFunctionFlags::ARROW}); + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetScope(funcScope); funcScope->BindNode(funcNode); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *arrowFuncNode = ProgramAllocNode(funcNode, ProgramAllocator()); + ES2PANDA_ASSERT(arrowFuncNode != nullptr); arrowFuncNode->SetParent(callExpr); ArenaVector fakeArguments = callExpr->Arguments(); diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 16cf1351d9..3a2652b5c4 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -2115,6 +2115,7 @@ Type *ETSChecker::CheckSwitchDiscriminant(ir::Expression *discriminant) { Type *discriminantType = discriminant->Check(this); discriminantType = GetNonConstantType(MaybeUnboxType(discriminantType)); + ES2PANDA_ASSERT(discriminantType != nullptr); if (!discriminantType->HasTypeFlag(TypeFlag::VALID_SWITCH_TYPE)) { if (!(discriminantType->IsETSObjectType() && discriminantType->AsETSObjectType()->HasObjectFlag( @@ -2473,7 +2474,9 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) std::stringstream ss; for (auto *p : type->Params()) { auto *const param = p->AsETSParameterExpression(); - param->TypeAnnotation()->GetType(this)->ToString(ss, true); + auto *paramType = param->TypeAnnotation()->GetType(this); + ES2PANDA_ASSERT(paramType != nullptr); + paramType->ToString(ss, true); ss << ";"; } @@ -2487,7 +2490,9 @@ util::StringView ETSChecker::GetHashFromFunctionType(ir::ETSFunctionType *type) } ss << "extensionFunction;"; } else { - type->ReturnType()->GetType(this)->ToString(ss, true); + auto *returnType = type->ReturnType()->GetType(this); + ES2PANDA_ASSERT(returnType != nullptr); + returnType->ToString(ss, true); } ss << ";"; @@ -2880,6 +2885,7 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty auto *methodIdent = property->Key()->AsIdentifier()->Clone(checker->ProgramAllocator(), nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *funcExpr = checker->ProgramAllocNode(func); + CHECK_NOT_NULL(funcExpr); funcExpr->SetRange(func->Range()); func->AddFlag(ir::ScriptFunctionFlags::METHOD); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) @@ -2889,17 +2895,20 @@ ir::MethodDefinition *ETSChecker::GenerateDefaultGetterSetter(ir::ClassProperty auto *decl = checker->ProgramAllocator()->New( checker->ProgramAllocator(), property->Key()->AsIdentifier()->Name(), method); auto *var = checker->ProgramAllocator()->New(decl, varbinder::VariableFlags::VAR); + CHECK_NOT_NULL(var); var->AddFlag(varbinder::VariableFlags::METHOD); methodIdent->SetVariable(var); - method->Id()->SetMutator(); - method->SetRange(field->Range()); auto *methodId = method->Id(); CHECK_NOT_NULL(methodId); + methodId->SetMutator(); + method->SetRange(field->Range()); + auto *methodFunc = method->Function(); + CHECK_NOT_NULL(methodFunc); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) - method->Function()->SetIdent(methodId->Clone(checker->ProgramAllocator(), nullptr)); - method->Function()->AddModifier(method->Modifiers()); + methodFunc->SetIdent(methodId->Clone(checker->ProgramAllocator(), nullptr)); + methodFunc->AddModifier(method->Modifiers()); method->SetVariable(var); method->SetParent(field->Parent()); @@ -3162,6 +3171,7 @@ Type *ETSChecker::GetImportSpecifierObjectType(ir::ETSImportDeclaration *importD ETSChecker::NamedAccessMeta ETSChecker::FormNamedAccessMetadata(varbinder::Variable const *prop) { + CHECK_NOT_NULL(prop); const auto *field = prop->Declaration()->Node()->AsClassProperty(); const auto *owner = field->Parent()->AsClassDefinition(); auto *fieldId = field->Id(); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index c72441cdc6..fc797866f7 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -627,7 +627,7 @@ static void ResolveDeclaredMethodsOfObject(ETSChecker *checker, const ETSObjectT if (it->Declaration()->Node()->IsMethodDefinition()) { auto *method = it->Declaration()->Node()->AsMethodDefinition(); auto *function = method->Function(); - + ES2PANDA_ASSERT(function != nullptr); if (function->IsProxy()) { continue; } @@ -794,8 +794,10 @@ void ETSChecker::CreateFunctionTypesFromAbstracts(const std::vector void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) { - auto cached = GetCachedComputedAbstracts()->find(interfaceType); - if (cached != GetCachedComputedAbstracts()->end()) { + auto cachedComputedAbstracts = GetCachedComputedAbstracts(); + ES2PANDA_ASSERT(cachedComputedAbstracts != nullptr); + auto cached = cachedComputedAbstracts->find(interfaceType); + if (cached != cachedComputedAbstracts->end()) { return; } @@ -808,8 +810,8 @@ void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) ArenaUnorderedSet abstractInheritanceTarget(ProgramAllocator()->Adapter()); for (auto *interface : interfaceType->Interfaces()) { - auto found = GetCachedComputedAbstracts()->find(interface); - ES2PANDA_ASSERT(found != GetCachedComputedAbstracts()->end()); + auto found = cachedComputedAbstracts->find(interface); + ES2PANDA_ASSERT(found != cachedComputedAbstracts->end()); if (!abstractInheritanceTarget.insert(found->first).second) { continue; @@ -822,7 +824,7 @@ void ETSChecker::ComputeAbstractsFromInterface(ETSObjectType *interfaceType) } } - GetCachedComputedAbstracts()->insert({interfaceType, {merged, abstractInheritanceTarget}}); + cachedComputedAbstracts->insert({interfaceType, {merged, abstractInheritanceTarget}}); } ArenaVector &ETSChecker::GetAbstractsForClass(ETSObjectType *classType) @@ -2335,9 +2337,9 @@ void ETSChecker::WarnForEndlessLoopInGetterSetter(const ir::MemberExpression *co } auto ident = memberExpr->Property()->AsIdentifier(); auto parent = memberExpr->Parent(); - while (parent != nullptr && - (!parent->IsMethodDefinition() || (!parent->AsMethodDefinition()->Function()->IsGetter() && - !parent->AsMethodDefinition()->Function()->IsSetter()))) { + while (parent != nullptr && (!parent->IsMethodDefinition() || parent->AsMethodDefinition()->Function() == nullptr || + (!parent->AsMethodDefinition()->Function()->IsGetter() && + !parent->AsMethodDefinition()->Function()->IsSetter()))) { parent = parent->Parent(); } if (parent != nullptr && parent->AsMethodDefinition()->Function() != nullptr && diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index ef96e14125..2950dd70d2 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -972,6 +972,7 @@ void ETSChecker::CheckAmbientAnnotation(ir::AnnotationDeclaration *annoImpl, ir: for (auto *prop : annoDecl->Properties()) { auto *field = prop->AsClassProperty(); + ES2PANDA_ASSERT(field->Id() != nullptr); fieldMap[field->Id()->Name()] = field; } @@ -1252,10 +1253,10 @@ void ETSChecker::CheckMultiplePropertiesAnnotation(ir::AnnotationUsage *st, util { for (auto *it : st->Properties()) { auto *param = it->AsClassProperty(); - auto result = fieldMap.find(param->Id()->Name()); + auto *id = param->Id(); + ES2PANDA_ASSERT(id != nullptr); + auto result = fieldMap.find(id->Name()); if (result == fieldMap.end()) { - auto *id = param->Id(); - ES2PANDA_ASSERT(id != nullptr); LogError(diagnostic::ANNOT_PROP_UNDEFINED, {id->Name(), baseName}, param->Start()); continue; } diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 33dac5f76d..0493a29be4 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -237,6 +237,7 @@ Signature *ETSChecker::CreateSignature(SignatureInfo *info, Type *returnType, ir return nullptr; } auto signature = ProgramAllocator()->New(info, returnType, nullptr); + ES2PANDA_ASSERT(signature != nullptr); signature->AddSignatureFlag(ConvertToSignatureFlags(ir::ModifierFlags::NONE, sff)); // synthetic arrow type signature flags auto extraFlags = SignatureFlags::ABSTRACT | SignatureFlags::CALL | SignatureFlags::PUBLIC; @@ -394,6 +395,7 @@ std::tuple ETSChecker::CreateBuiltinArraySign util::UString param(std::to_string(i), ProgramAllocator()); auto *paramVar = varbinder::Scope::CreateVar(ProgramAllocator(), param.View(), varbinder::VariableFlags::NONE, nullptr); + ES2PANDA_ASSERT(paramVar != nullptr); paramVar->SetTsType(GlobalIntType()); info->params.push_back(paramVar); diff --git a/ets2panda/checker/ets/typeRelationContext.h b/ets2panda/checker/ets/typeRelationContext.h index eeb2ba008d..ae20ce5ad1 100644 --- a/ets2panda/checker/ets/typeRelationContext.h +++ b/ets2panda/checker/ets/typeRelationContext.h @@ -34,6 +34,8 @@ public: auto *const etsChecker = relation->GetChecker()->AsETSChecker(); + ES2PANDA_ASSERT(target != nullptr); + ES2PANDA_ASSERT(node != nullptr); if (target->IsETSArrayType() && node->IsArrayExpression()) { assignable_ = ValidateArrayTypeInitializerByElement(relation, node->AsArrayExpression(), target->AsETSArrayType()); diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 0224e9882e..284a11b3c1 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -242,6 +242,7 @@ ir::ClassProperty *ETSChecker::CreateNullishPropertyFromAccessor(ir::MethodDefin ES2PANDA_ASSERT(id != nullptr); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *ident = id->Clone(ProgramAllocator(), nullptr); + ES2PANDA_ASSERT(accessor->Function() != nullptr); auto modifierFlag = accessor->Function()->IsGetter() && accessor->Overloads().empty() ? ir::ModifierFlags::READONLY : ir::ModifierFlags::NONE; @@ -375,6 +376,7 @@ ir::TSTypeParameterDeclaration *ETSChecker::ProcessTypeParamAndGenSubstitution( CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->Constraint(), ProgramAllocator()), // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) CloneNodeIfNotNullptr(classOrInterfaceDefTypeParam->DefaultType(), ProgramAllocator()), ProgramAllocator()); + ES2PANDA_ASSERT(newTypeParam != nullptr); newTypeParams->AddParam(newTypeParam); newTypeParam->SetParent(newTypeParams); ES2PANDA_ASSERT(likeSubstitution != nullptr); @@ -414,6 +416,7 @@ ir::TSTypeParameterInstantiation *ETSChecker::CreateNewSuperPartialRefTypeParams typeParamRefPart->Name()->SetParent(typeParamRefPart); // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *typeParamRef = ProgramAllocNode(typeParamRefPart, ProgramAllocator()); + ES2PANDA_ASSERT(typeParamRef != nullptr); typeParamRefPart->SetParent(typeParamRef); typeParamRef->SetParent(superPartialRefTypeParams); @@ -473,7 +476,7 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ProgramAllocNode(std::move(typeParams), classDef->TypeParams()->RequiredParams()); - + ES2PANDA_ASSERT(newTypeParams != nullptr); newClassDefinition->SetTypeParams(newTypeParams); newTypeParams->SetParent(newClassDefinition); } @@ -485,7 +488,8 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla // Only handle class properties (members) // Method calls on partial classes will make the class not type safe, so we don't copy any methods if (prop->IsClassProperty()) { - if (prop->AsClassProperty()->Id()->Name().Mutf8().find(compiler::Signatures::PROPERTY, 0) == 0) { + if (prop->AsClassProperty()->Id() == nullptr || + prop->AsClassProperty()->Id()->Name().Mutf8().find(compiler::Signatures::PROPERTY, 0) == 0) { continue; } @@ -499,6 +503,7 @@ void ETSChecker::CreatePartialClassDeclaration(ir::ClassDefinition *const newCla (prop->AsMethodDefinition()->Function()->IsGetter() || prop->AsMethodDefinition()->Function()->IsSetter())) { auto *method = prop->AsMethodDefinition(); + ES2PANDA_ASSERT(method->Id() != nullptr); if (newClassDefinition->Scope()->FindLocal(method->Id()->Name(), varbinder::ResolveBindingOptions::VARIABLES) != nullptr) { continue; @@ -622,6 +627,7 @@ ir::TSInterfaceDeclaration *ETSChecker::CreateInterfaceProto(util::StringView na Language(Language::Id::ETS)}); const auto classCtx = varbinder::LexicalScope(VarBinder()); + ES2PANDA_ASSERT(partialInterface != nullptr); partialInterface->TypeParams()->SetParent(partialInterface); partialInterface->SetScope(classCtx.GetScope()); partialInterface->SetVariable(var); @@ -684,6 +690,7 @@ void ETSChecker::CreatePartialTypeInterfaceMethods(ir::TSInterfaceDeclaration *c } for (auto *overload : method->Overloads()) { + ES2PANDA_ASSERT(overload->Function() != nullptr); if (overload->Function()->IsGetter() || overload->Function()->IsSetter()) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) addNullishAccessor(CreateNullishAccessor(overload, partialInterface)); @@ -786,6 +793,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par // Create class name, and declaration variable // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) auto *const classId = ProgramAllocNode(name, ProgramAllocator()); + ES2PANDA_ASSERT(classId != nullptr); const auto [decl, var] = VarBinder()->NewVarDecl(classId->Start(), classId->Name()); classId->SetVariable(var); @@ -795,6 +803,7 @@ ir::ClassDefinition *ETSChecker::CreateClassPrototype(util::StringView name, par // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) ProgramAllocNode(ProgramAllocator(), classId, ir::ClassDefinitionModifiers::DECLARATION, ir::ModifierFlags::NONE, Language(Language::Id::ETS)); + ES2PANDA_ASSERT(classDef != nullptr); classDef->SetScope(classCtx.GetScope()); classDef->SetVariable(var); @@ -915,7 +924,7 @@ std::pair ETSChecker::CreateScriptFuncti ir::ScriptFunctionFlags::CONSTRUCTOR | ir::ScriptFunctionFlags::EXPRESSION, ir::ModifierFlags::PUBLIC}); - + ES2PANDA_ASSERT(func != nullptr); func->SetScope(scope); scope->BindNode(func); func->SetIdent(id); @@ -976,6 +985,7 @@ Type *ETSChecker::GetReadonlyType(Type *type) if (type->IsETSArrayType()) { ETSArrayType *const clonedArrayType = ProgramAllocator()->New(type->AsETSArrayType()->ElementType()); + ES2PANDA_ASSERT(clonedArrayType != nullptr); clonedArrayType->AddTypeFlag(TypeFlag::READONLY); return clonedArrayType; } diff --git a/ets2panda/checker/ts/destructuringContext.cpp b/ets2panda/checker/ts/destructuringContext.cpp index db1636c4d1..62212a8fca 100644 --- a/ets2panda/checker/ts/destructuringContext.cpp +++ b/ets2panda/checker/ts/destructuringContext.cpp @@ -154,7 +154,7 @@ void DestructuringContext::HandleAssignmentPattern(ir::AssignmentExpression *ass if (!checker_->HasStatus(CheckerStatus::IN_CONST_CONTEXT)) { defaultType = checker_->GetBaseTypeOfLiteralType(defaultType); } - + ES2PANDA_ASSERT(defaultType != nullptr); if (validateDefault && assignmentPattern->Right()->IsObjectExpression() && assignmentPattern->Left()->IsObjectPattern()) { ValidateObjectLiteralType(defaultType->AsObjectType(), assignmentPattern->Left()->AsObjectPattern()); @@ -560,6 +560,7 @@ Type *ObjectDestructuringContext::CreateObjectTypeForRest(ObjectType *objType) if (!it->HasFlag(varbinder::VariableFlags::INFERRED_IN_PATTERN)) { auto *memberVar = varbinder::Scope::CreateVar(checker_->Allocator(), it->Name(), varbinder::VariableFlags::NONE, nullptr); + ES2PANDA_ASSERT(memberVar != nullptr); memberVar->SetTsType(it->TsType()); memberVar->AddFlag(it->Flags()); ES2PANDA_ASSERT(desc != nullptr); @@ -568,6 +569,7 @@ Type *ObjectDestructuringContext::CreateObjectTypeForRest(ObjectType *objType) } Type *returnType = checker_->Allocator()->New(desc); + ES2PANDA_ASSERT(returnType != nullptr); returnType->AsObjectType()->AddObjectFlag(ObjectFlags::RESOLVED_MEMBERS); return returnType; } diff --git a/ets2panda/checker/ts/function.cpp b/ets2panda/checker/ts/function.cpp index b572291219..7b0634260a 100644 --- a/ets2panda/checker/ts/function.cpp +++ b/ets2panda/checker/ts/function.cpp @@ -149,8 +149,9 @@ Type *TSChecker::CreateParameterTypeForArrayAssignmentPattern(ir::ArrayExpressio return inferredType; } - TupleType *newTuple = - inferredTuple->Instantiate(Allocator(), Relation(), GetGlobalTypesHolder())->AsObjectType()->AsTupleType(); + auto initTuple = inferredTuple->Instantiate(Allocator(), Relation(), GetGlobalTypesHolder()); + ES2PANDA_ASSERT(initTuple != nullptr); + TupleType *newTuple = initTuple->AsObjectType()->AsTupleType(); for (uint32_t index = inferredTuple->FixedLength(); index < arrayPattern->Elements().size(); index++) { util::StringView memberIndex = util::Helpers::ToStringView(Allocator(), index); @@ -392,6 +393,7 @@ std::tuple TSCheck if (cache) { Type *placeholder = Allocator()->New(GlobalAnyType()); + ES2PANDA_ASSERT(placeholder != nullptr); placeholder->SetVariable(std::get<0>(result)); param->SetTsType(placeholder); } @@ -609,14 +611,16 @@ void TSChecker::InferFunctionDeclarationType(const varbinder::FunctionDecl *decl if (descWithOverload->callSignatures.empty()) { Type *funcType = CreateFunctionTypeWithSignature(bodyCallSignature); + ES2PANDA_ASSERT(funcType != nullptr); funcType->SetVariable(funcVar); funcVar->SetTsType(funcType); } - + ES2PANDA_ASSERT(bodyCallSignature != nullptr); bodyCallSignature->SetReturnType(HandleFunctionReturn(bodyDeclaration)); if (!descWithOverload->callSignatures.empty()) { Type *funcType = Allocator()->New(descWithOverload); + ES2PANDA_ASSERT(funcType != nullptr); funcType->SetVariable(funcVar); funcVar->SetTsType(funcType); diff --git a/ets2panda/checker/ts/object.cpp b/ets2panda/checker/ts/object.cpp index bf9d836a98..0c9e3c25c3 100644 --- a/ets2panda/checker/ts/object.cpp +++ b/ets2panda/checker/ts/object.cpp @@ -152,6 +152,7 @@ void TSChecker::ResolveUnionTypeMembers(UnionType *type) } ObjectType *mergedType = Allocator()->New(desc); + ES2PANDA_ASSERT(mergedType != nullptr); mergedType->AddObjectFlag(ObjectFlags::RESOLVED_MEMBERS); type->SetMergedObjectType(mergedType); } @@ -388,6 +389,7 @@ IndexInfo *TSChecker::GetApplicableIndexInfo(Type *type, Type *indexType) Type *TSChecker::GetPropertyTypeForIndexType(Type *type, Type *indexType) { + ES2PANDA_ASSERT(type != nullptr); if (type->IsArrayType()) { return type->AsArrayType()->ElementType(); } diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index c55afdffc6..ae07ae9762 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -77,7 +77,7 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, if (signature->RestVar() != nullptr) { auto nPosParams = signature->Params().size(); - auto *functionN = checker->GlobalBuiltinFunctionType(nPosParams, true)->AsETSObjectType(); + auto *functionN = checker->GlobalBuiltinFunctionType(nPosParams, true); auto substitution = Substitution {}; for (size_t i = 0; i < nPosParams; i++) { substitution.emplace(functionN->TypeArguments()[i]->AsETSTypeParameter(), @@ -102,7 +102,7 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, return nullptr; } - auto *funcIface = checker->GlobalBuiltinFunctionType(arity, false)->AsETSObjectType(); + auto *funcIface = checker->GlobalBuiltinFunctionType(arity, false); auto substitution = Substitution {}; for (size_t i = 0; i < arity; i++) { diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index bf8e96f62d..9834924f2e 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -235,6 +235,7 @@ varbinder::LocalVariable *ETSObjectType::CreateSyntheticVarFromEverySignature(co varbinder::LocalVariable *res = allocator_->New(varianceFlag); ETSFunctionType *funcType = CreateMethodTypeForProp(name); + ES2PANDA_ASSERT(funcType != nullptr); for (auto &s : signatures) { funcType->AddCallSignature(s); } diff --git a/ets2panda/checker/types/signature.cpp b/ets2panda/checker/types/signature.cpp index a1db9138f6..0aaeab3066 100644 --- a/ets2panda/checker/types/signature.cpp +++ b/ets2panda/checker/types/signature.cpp @@ -115,7 +115,7 @@ void Signature::ToAssemblerType(std::stringstream &ss) const Signature *Signature::Copy(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) { SignatureInfo *copiedInfo = allocator->New(signatureInfo_, allocator); - + ES2PANDA_ASSERT(copiedInfo != nullptr); for (size_t idx = 0U; idx < signatureInfo_->params.size(); ++idx) { auto *const paramType = signatureInfo_->params[idx]->TsType()->MaybeBaseTypeOfGradualType(); if (paramType->HasTypeFlag(TypeFlag::GENERIC) && paramType->IsETSObjectType()) { @@ -296,6 +296,7 @@ Signature *Signature::ToArrowSignature(ETSChecker *checker) auto *retType = checker->MaybeBoxType(returnType_); auto *resultSig = allocator->New(sigInfo, retType); + ES2PANDA_ASSERT(resultSig != nullptr); resultSig->flags_ = flags_; resultSig->SetOwner(Owner()); resultSig->SetOwnerVar(OwnerVar()); diff --git a/ets2panda/checker/types/ts/objectDescriptor.cpp b/ets2panda/checker/types/ts/objectDescriptor.cpp index 6dfe4e610e..ccd7d48a60 100644 --- a/ets2panda/checker/types/ts/objectDescriptor.cpp +++ b/ets2panda/checker/types/ts/objectDescriptor.cpp @@ -38,8 +38,8 @@ void ObjectDescriptor::Copy(ArenaAllocator *allocator, ObjectDescriptor *copiedD // copy by hand for (auto *it : properties) { auto *copiedProp = it->Copy(allocator, it->Declaration()); + ES2PANDA_ASSERT(copiedProp != nullptr); copiedProp->SetTsType(it->TsType()->Instantiate(allocator, relation, globalTypes)); - ES2PANDA_ASSERT(copiedDesc != nullptr); copiedDesc->properties.push_back(copiedProp); } diff --git a/ets2panda/parser/ASparser.cpp b/ets2panda/parser/ASparser.cpp index 9c5f9cb7cc..f2567fef3d 100644 --- a/ets2panda/parser/ASparser.cpp +++ b/ets2panda/parser/ASparser.cpp @@ -578,6 +578,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationLiteralIdentHelper(ir::TypeNode *type ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); + ES2PANDA_ASSERT(type != nullptr); type->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -656,6 +657,7 @@ ir::TypeNode *ASParser::ParseTypeAnnotationTokens(ir::TypeNode *type, bool throw ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); type = AllocNode(typeName, Allocator()); + ES2PANDA_ASSERT(type != nullptr); type->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); return type; @@ -893,6 +895,7 @@ ArenaVector ASParser::ParseInterfaceExtendsClause() ES2PANDA_ASSERT(extendsName != nullptr); extendsName->SetRange(Lexer()->GetToken().Loc()); auto *extendsClause = AllocNode(extendsName, Allocator()); + ES2PANDA_ASSERT(extendsClause != nullptr); extendsClause->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -1154,6 +1157,7 @@ ArenaVector ASParser::ParseClassImplementClause() } auto *impl = AllocNode(current, implTypeParams); + ES2PANDA_ASSERT(impl != nullptr); impl->SetRange({implementStart, Lexer()->GetToken().End()}); implements.push_back(impl); diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9e2059c27d..3d0f8572e0 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -306,6 +306,7 @@ void ETSParser::ParseParseListElement(const util::ImportPathManager::ParseInfo & { const auto &importData = parseListElem.importData; auto src = importData.HasSpecifiedDeclPath() ? importData.declPath : importData.resolvedSource; + ES2PANDA_ASSERT(extSrc != nullptr); SourceFile sf {src, extSrc->View().Utf8(), importData.resolvedSource, false, importData.HasSpecifiedDeclPath()}; parser::Program *newProg = ParseSource(sf); ES2PANDA_ASSERT(newProg != nullptr); @@ -1217,6 +1218,7 @@ ir::ETSImportDeclaration *ETSParser::ParseImportPathBuildImport(ArenaVectorGetToken().Type() == lexer::TokenType::LITERAL_STRING); auto pathToResolve = Lexer()->GetToken().Ident(); auto *importPathStringLiteral = AllocNode(pathToResolve); + ES2PANDA_ASSERT(importPathStringLiteral != nullptr); importPathStringLiteral->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); auto importFlags = (GetContext().Status() & parser::ParserStatus::IN_DEFAULT_IMPORTS) != 0U @@ -1566,6 +1568,7 @@ ir::AstNode *ETSParser::ParseImportDefaultSpecifier(ArenaVector * } auto *specifier = AllocNode(imported); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({imported->Start(), imported->End()}); specifiers->push_back(specifier); @@ -2116,7 +2119,6 @@ ir::TSTypeParameter *ETSParser::ParseTypeParameter([[maybe_unused]] TypeAnnotati auto *typeParam = AllocNode(paramIdent, constraint, defaultType, varianceModifier, Allocator()); - ES2PANDA_ASSERT(typeParam); ES2PANDA_ASSERT(typeParam != nullptr); ApplyAnnotationsToNode(typeParam, std::move(annotations), saveLoc); @@ -2349,6 +2351,7 @@ ir::FunctionDeclaration *ETSParser::ParseAccessorWithReceiver(ir::ModifierFlags func->SetIdent(funcIdentNode); auto *funcDecl = AllocNode(Allocator(), func); + ES2PANDA_ASSERT(funcDecl != nullptr); funcDecl->SetRange(func->Range()); func->AddModifier(modifiers); func->SetStart(startLoc); diff --git a/ets2panda/parser/ETSparserAnnotations.cpp b/ets2panda/parser/ETSparserAnnotations.cpp index f5f9d5c3a9..1194431c69 100644 --- a/ets2panda/parser/ETSparserAnnotations.cpp +++ b/ets2panda/parser/ETSparserAnnotations.cpp @@ -132,6 +132,7 @@ ArenaVector ETSParser::ParseAnnotationProperties(ir::ModifierFlag } auto *fieldName = ExpectIdentifier(); + ES2PANDA_ASSERT(fieldName != nullptr); if (fieldName->IsErrorPlaceHolder()) { // Try to recover from error: simplest strategy: only one step ahead. // Probably we can seek for identifier till the enclosing right brace (staring after the next comma?) @@ -401,6 +402,7 @@ ir::AnnotationUsage *ETSParser::ParseAnnotationUsage() auto *singleParam = AllocNode(singleParamName, initializer, nullptr, ir::ModifierFlags::ANNOTATION_USAGE, Allocator(), false); + ES2PANDA_ASSERT(singleParam != nullptr); singleParam->SetRange( {singleParamName->Start(), initializer != nullptr ? initializer->End() : singleParamName->End()}); properties.push_back(singleParam); diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 8807006489..02fd4ea2fe 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -436,6 +436,7 @@ ir::TypeNode *ETSParser::ConvertToOptionalUnionType(ir::TypeNode *typeAnno) types.push_back(AllocNode(Allocator())); types.back()->SetRange(typeAnno->Range()); auto *newTypeAnno = AllocNode(std::move(types), Allocator()); + ES2PANDA_ASSERT(newTypeAnno != nullptr); newTypeAnno->SetRange(typeAnno->Range()); return newTypeAnno; } @@ -597,6 +598,7 @@ ir::MethodDefinition *ETSParser::ParseClassMethodDefinition(ir::Identifier *meth auto *method = AllocNode(methodKind, methodName->Clone(Allocator(), nullptr)->AsExpression(), funcExpr, modifiers, Allocator(), false); + ES2PANDA_ASSERT(method != nullptr); method->SetDefaultAccessModifier(isDefault); method->SetRange(funcExpr->Range()); return method; @@ -1396,6 +1398,7 @@ void ETSParser::CreateImplicitConstructor([[maybe_unused]] ir::MethodDefinition } auto *methodDef = BuildImplicitConstructor(ir::ClassDefinitionModifiers::SET_CTOR_ID, startLoc); + ES2PANDA_ASSERT(methodDef != nullptr); if ((flags & ir::ModifierFlags::DECLARE) != 0) { auto func = methodDef->Function(); ES2PANDA_ASSERT(func != nullptr); diff --git a/ets2panda/parser/ETSparserExpressions.cpp b/ets2panda/parser/ETSparserExpressions.cpp index 7cd587f214..2a1349fc55 100644 --- a/ets2panda/parser/ETSparserExpressions.cpp +++ b/ets2panda/parser/ETSparserExpressions.cpp @@ -45,6 +45,7 @@ ir::Expression *ETSParser::ParseFunctionParameterExpression(ir::AnnotatedExpress auto const lexerPos = Lexer()->Save().Iterator(); Lexer()->NextToken(); // eat '=' + ES2PANDA_ASSERT(paramIdent != nullptr); if (paramIdent->IsRestElement()) { LogError(diagnostic::NO_DEFAULT_FOR_REST); } @@ -687,6 +688,7 @@ ir::Expression *ETSParser::ParseNewExpression() ParseArgumentsNewExpression(arguments, typeReference); auto *newExprNode = AllocNode(typeReference, std::move(arguments)); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, Lexer()->GetToken().End()}); return newExprNode; diff --git a/ets2panda/parser/TSparser.cpp b/ets2panda/parser/TSparser.cpp index 402df097d4..d2545ce425 100644 --- a/ets2panda/parser/TSparser.cpp +++ b/ets2panda/parser/TSparser.cpp @@ -528,7 +528,7 @@ ir::TypeNode *TSParser::ParseTypeOperatorOrTypeReference() ir::TypeNode *type = ParseTypeAnnotation(&options); auto *typeOperator = AllocNode(type, ir::TSOperatorType::KEYOF, Allocator()); - + ES2PANDA_ASSERT(typeOperator != nullptr); typeOperator->SetRange({typeOperatorStart, type->End()}); return typeOperator; @@ -693,6 +693,7 @@ ir::TypeNode *TSParser::ParseTypeReferenceOrQuery(bool parseQuery) Lexer()->GetToken().Type() == lexer::TokenType::KEYW_EXTENDS); ir::Expression *typeName = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(typeName != nullptr); typeName->SetRange(Lexer()->GetToken().Loc()); if (Lexer()->Lookahead() == lexer::LEX_CHAR_LESS_THAN) { diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index cc626c2ed9..abcc50ff8b 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -341,6 +341,7 @@ ir::TSModuleDeclaration *TypedParser::ParseModuleOrNamespaceDeclaration(const le auto *moduleDecl = AllocNode(Allocator(), identNode, body, ir::TSModuleDeclaration::ConstructorFlags {false, false}); + ES2PANDA_ASSERT(moduleDecl != nullptr); moduleDecl->SetRange({startLoc, Lexer()->GetToken().End()}); return moduleDecl; @@ -439,6 +440,7 @@ ir::TypeNode *TypedParser::ParseInterfaceExtendsElement() } auto *typeReference = AllocNode(expr, typeParamInst, Allocator()); + ES2PANDA_ASSERT(typeReference != nullptr); typeReference->SetRange({heritageStart, heritageEnd}); return typeReference; } @@ -774,7 +776,7 @@ ir::TSTypeParameter *TypedParser::ParseTypeParameter(TypeAnnotationParsingOption } auto *typeParam = AllocNode(paramIdent, constraint, defaultType, Allocator()); - + ES2PANDA_ASSERT(typeParam != nullptr); typeParam->SetRange({startLoc, Lexer()->GetToken().End()}); return typeParam; diff --git a/ets2panda/parser/context/classPrivateContext.cpp b/ets2panda/parser/context/classPrivateContext.cpp index d191b3b597..048ec7177a 100644 --- a/ets2panda/parser/context/classPrivateContext.cpp +++ b/ets2panda/parser/context/classPrivateContext.cpp @@ -25,7 +25,7 @@ bool ClassPrivateContext::AddElement(const ir::ClassElement *elem) { bool newPropIsStatic = elem->IsStatic(); auto id = elem->Id(); - ES2PANDA_ASSERT(id); + ES2PANDA_ASSERT(id != nullptr); util::StringView newPropName = id->Name(); ir::MethodDefinitionKind newPropMethodKind = ir::MethodDefinitionKind::METHOD; @@ -64,7 +64,7 @@ bool ClassPrivateContext::FindElement(const ir::Identifier *elem) const { for (const auto *it : elements_) { auto id = it->Id(); - ES2PANDA_ASSERT(id); + ES2PANDA_ASSERT(id != nullptr); if (id->Name().Compare(elem->Name()) == 0) { return true; } diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 24a4b657b3..cc0f836b18 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -114,7 +114,7 @@ ir::YieldExpression *ParserImpl::ParseYieldExpression() } auto *yieldNode = AllocNode(argument, isDelegate); - ES2PANDA_ASSERT(yieldNode); + ES2PANDA_ASSERT(yieldNode != nullptr); yieldNode->SetRange({startLoc, endLoc}); return yieldNode; @@ -209,7 +209,7 @@ ir::ArrayExpression *ParserImpl::ParseArrayExpression(ExpressionParseFlags flags auto nodeType = inPattern ? ir::AstNodeType::ARRAY_PATTERN : ir::AstNodeType::ARRAY_EXPRESSION; auto *arrayExpressionNode = AllocNode(nodeType, std::move(elements), Allocator(), trailingComma); - ES2PANDA_ASSERT(arrayExpressionNode); + ES2PANDA_ASSERT(arrayExpressionNode != nullptr); arrayExpressionNode->SetRange({startLoc, endLoc}); if (inPattern) { @@ -344,6 +344,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParseArrowFunctionExpressionBody(ArrowF {}, context_.GetLanguage()}); // clang-format on + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({desc->startLoc, endLoc}); auto *arrowFuncNode = AllocNode(funcNode, Allocator()); @@ -584,7 +585,7 @@ ir::Expression *ParserImpl::CreateBinaryAssignmentExpression(ir::Expression *ass auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); - ES2PANDA_ASSERT(binaryAssignmentExpression); + ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -600,7 +601,7 @@ ir::Expression *ParserImpl::ParseAssignmentExpression(ir::Expression *lhsExpress ir::Expression *consequent = ParseAssignmentExpressionHelper(); ir::Expression *alternate = ParseExpression(); auto *conditionalExpr = AllocNode(lhsExpression, consequent, alternate); - ES2PANDA_ASSERT(conditionalExpr); + ES2PANDA_ASSERT(conditionalExpr != nullptr); conditionalExpr->SetRange({lhsExpression->Start(), alternate->End()}); return conditionalExpr; } @@ -714,7 +715,7 @@ ir::Expression *ParserImpl::ParseAssignmentEqualExpression(const lexer::TokenTyp auto *binaryAssignmentExpression = AllocNode(lhsExpression, assignmentExpression, tokenType); - ES2PANDA_ASSERT(binaryAssignmentExpression); + ES2PANDA_ASSERT(binaryAssignmentExpression != nullptr); binaryAssignmentExpression->SetRange({lhsExpression->Start(), assignmentExpression->End()}); return binaryAssignmentExpression; @@ -755,6 +756,7 @@ ir::TemplateLiteral *ParserImpl::ParseTemplateLiteral() const auto templateStr = lexer_->ScanTemplateString(); if (templateStr.validSequence) { auto *const element = AllocNode(templateStr.str.View(), cooked); + ES2PANDA_ASSERT(element != nullptr); element->SetRange({lexer::SourcePosition {startPos.Iterator().Index(), startPos.Line(), GetProgram()}, lexer::SourcePosition {templateStr.end, lexer_->Line(), GetProgram()}}); quasis.push_back(element); @@ -805,7 +807,7 @@ ir::Expression *ParserImpl::ParseNewExpression() if (lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_LEFT_PARENTHESIS) { lexer::SourcePosition endLoc = callee->End(); auto *newExprNode = AllocNode(callee, std::move(arguments)); - ES2PANDA_ASSERT(newExprNode); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -831,7 +833,7 @@ ir::Expression *ParserImpl::ParseNewExpression() &endLoc, true); auto *newExprNode = AllocNode(callee, std::move(arguments)); - ES2PANDA_ASSERT(newExprNode); + ES2PANDA_ASSERT(newExprNode != nullptr); newExprNode->SetRange({start, endLoc}); return newExprNode; @@ -860,7 +862,7 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() } auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::NEW_TARGET); - ES2PANDA_ASSERT(metaProperty); + ES2PANDA_ASSERT(metaProperty != nullptr); metaProperty->SetRange(loc); lexer_->NextToken(); return metaProperty; @@ -873,7 +875,7 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() ir::Identifier *ParserImpl::ParsePrimaryExpressionIdent([[maybe_unused]] ExpressionParseFlags flags) { auto *identNode = AllocNode(lexer_->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(identNode); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -886,7 +888,7 @@ ir::BooleanLiteral *ParserImpl::ParseBooleanLiteral() lexer_->GetToken().Type() == lexer::TokenType::LITERAL_FALSE); auto *booleanNode = AllocNode(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_TRUE); - ES2PANDA_ASSERT(booleanNode); + ES2PANDA_ASSERT(booleanNode != nullptr); booleanNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -897,7 +899,7 @@ ir::NullLiteral *ParserImpl::ParseNullLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_NULL); auto *nullNode = AllocNode(); - ES2PANDA_ASSERT(nullNode); + ES2PANDA_ASSERT(nullNode != nullptr); nullNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -916,7 +918,7 @@ ir::Literal *ParserImpl::ParseNumberLiteral() numberNode = AllocNode(lexer_->GetToken().GetNumber()); } - ES2PANDA_ASSERT(numberNode); + ES2PANDA_ASSERT(numberNode != nullptr); numberNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -928,7 +930,7 @@ ir::CharLiteral *ParserImpl::ParseCharLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_CHAR); auto *charNode = AllocNode(lexer_->GetToken().Utf16()); - ES2PANDA_ASSERT(charNode); + ES2PANDA_ASSERT(charNode != nullptr); charNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -940,7 +942,7 @@ ir::StringLiteral *ParserImpl::ParseStringLiteral() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::LITERAL_STRING); auto *stringNode = AllocNode(lexer_->GetToken().String()); - ES2PANDA_ASSERT(stringNode); + ES2PANDA_ASSERT(stringNode != nullptr); stringNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -951,7 +953,7 @@ ir::UndefinedLiteral *ParserImpl::ParseUndefinedLiteral() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_UNDEFINED); auto *undefinedNode = AllocNode(); - ES2PANDA_ASSERT(undefinedNode); + ES2PANDA_ASSERT(undefinedNode != nullptr); undefinedNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -983,7 +985,7 @@ ir::RegExpLiteral *ParserImpl::ParseRegularExpression() reParser.ParsePattern(); auto *regexpNode = AllocNode(regexp.patternStr, regexp.flags, regexp.flagsStr); - ES2PANDA_ASSERT(regexpNode); + ES2PANDA_ASSERT(regexpNode != nullptr); regexpNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -995,7 +997,7 @@ ir::SuperExpression *ParserImpl::ParseSuperExpression() ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_SUPER); auto *superExprNode = AllocNode(); - ES2PANDA_ASSERT(superExprNode); + ES2PANDA_ASSERT(superExprNode != nullptr); superExprNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); // eat super @@ -1044,7 +1046,7 @@ ir::Expression *ParserImpl::ParseHashMaskOperator() } auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(privateIdent); + ES2PANDA_ASSERT(privateIdent != nullptr); privateIdent->SetPrivate(true); lexer_->NextToken(); @@ -1066,7 +1068,7 @@ ir::Expression *ParserImpl::ParseClassExpression() } auto *classExpr = AllocNode(classDefinition); - ES2PANDA_ASSERT(classExpr); + ES2PANDA_ASSERT(classExpr != nullptr); classExpr->SetRange({startLoc, classDefinition->End()}); return classExpr; @@ -1305,7 +1307,7 @@ void ParserImpl::CreateAmendedBinaryExpression(ir::Expression *const left, ir::E amended->SetParent(nullptr); // Next line overwrite parent auto *binaryExpr = AllocNode(left, amended, operatorType); - ES2PANDA_ASSERT(binaryExpr); + ES2PANDA_ASSERT(binaryExpr != nullptr); binaryExpr->SetRange({left->Start(), amended->End()}); SetAmendedChildExpression(right, binaryExpr); } @@ -1364,7 +1366,7 @@ ir::Expression *ParserImpl::ParseBinaryExpression(ir::Expression *left, const le } const lexer::SourcePosition &endPos = rightExpr->End(); rightExpr = AllocNode(left, rightExpr, operatorType); - ES2PANDA_ASSERT(rightExpr); + ES2PANDA_ASSERT(rightExpr != nullptr); rightExpr->SetRange({left->Start(), endPos}); } @@ -1430,7 +1432,7 @@ ir::CallExpression *ParserImpl::ParseCallExpression(ir::Expression *callee, bool callExpr = AllocNode(callee, std::move(arguments), nullptr, isOptionalChain, trailingComma); } - ES2PANDA_ASSERT(callExpr); + ES2PANDA_ASSERT(callExpr != nullptr); callExpr->SetRange({callee->Start(), endLoc}); isOptionalChain = false; @@ -1463,12 +1465,13 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) const auto tokenType = lexer_->GetToken().Type(); if (tokenType == lexer::TokenType::LITERAL_IDENT) { auto *identNode = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetPrivate(isPrivate); identNode->SetRange(lexer_->GetToken().Loc()); returnExpression = AllocNode(leftSideExpr, identNode, ir::MemberExpressionKind::PROPERTY_ACCESS, false, true); - ES2PANDA_ASSERT(returnExpression); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({leftSideExpr->Start(), identNode->End()}); lexer_->NextToken(); } @@ -1485,7 +1488,7 @@ ir::Expression *ParserImpl::ParseOptionalChain(ir::Expression *leftSideExpr) returnExpression = AllocNode(leftSideExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, true); - ES2PANDA_ASSERT(returnExpression); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({leftSideExpr->Start(), endLoc}); lexer_->NextToken(); } @@ -1509,7 +1512,7 @@ ir::ArrowFunctionExpression *ParserImpl::ParsePotentialArrowExpression(ir::Expre switch (lexer_->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); - ES2PANDA_ASSERT(returnExpression); + ES2PANDA_ASSERT(returnExpression != nullptr); (*returnExpression)->SetStart(startLoc); break; } @@ -1585,7 +1588,7 @@ ir::MemberExpression *ParserImpl::ParseElementAccess(ir::Expression *primaryExpr auto *memberExpr = AllocNode(primaryExpr, propertyNode, ir::MemberExpressionKind::ELEMENT_ACCESS, true, isOptional); - ES2PANDA_ASSERT(memberExpr); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), lexer_->GetToken().End()}); lexer_->NextToken(); return memberExpr; @@ -1599,14 +1602,14 @@ ir::MemberExpression *ParserImpl::ParsePrivatePropertyAccess(ir::Expression *pri ValidatePrivateIdentifier(); auto *privateIdent = AllocNode(lexer_->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(privateIdent); + ES2PANDA_ASSERT(privateIdent != nullptr); privateIdent->SetRange({memberStart, lexer_->GetToken().End()}); privateIdent->SetPrivate(true); lexer_->NextToken(); auto *memberExpr = AllocNode(primaryExpr, privateIdent, ir::MemberExpressionKind::PROPERTY_ACCESS, false, false); - ES2PANDA_ASSERT(memberExpr); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), privateIdent->End()}); return memberExpr; } @@ -1616,7 +1619,7 @@ ir::MemberExpression *ParserImpl::ParsePropertyAccess(ir::Expression *primaryExp ir::Identifier *ident = ExpectIdentifier(true); auto *memberExpr = AllocNode(primaryExpr, ident, ir::MemberExpressionKind::PROPERTY_ACCESS, false, isOptional); - ES2PANDA_ASSERT(memberExpr); + ES2PANDA_ASSERT(memberExpr != nullptr); memberExpr->SetRange({primaryExpr->Start(), ident->End()}); return memberExpr; @@ -1679,11 +1682,11 @@ ir::Expression *ParserImpl::ParsePostPrimaryExpressionBackTick(ir::Expression *r const lexer::SourcePosition startLoc) { ir::TemplateLiteral *propertyNode = ParseTemplateLiteral(); - ES2PANDA_ASSERT(propertyNode); + ES2PANDA_ASSERT(propertyNode != nullptr); lexer::SourcePosition endLoc = propertyNode->End(); returnExpression = AllocNode(returnExpression, propertyNode, nullptr); - ES2PANDA_ASSERT(returnExpression); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({startLoc, endLoc}); return returnExpression; @@ -1744,7 +1747,7 @@ ir::Expression *ParserImpl::SetupChainExpr(ir::Expression *const top, lexer::Sou lexer::SourcePosition endLoc = expr->End(); auto chain = AllocNode(expr); - ES2PANDA_ASSERT(chain); + ES2PANDA_ASSERT(chain != nullptr); chain->SetRange({startLoc, endLoc}); if (expr == top) { @@ -1793,7 +1796,7 @@ ir::Expression *ParserImpl::ParseMemberExpression(bool ignoreCallExpression, Exp returnExpression = AllocNode(returnExpression, lexer_->GetToken().Type(), false); - ES2PANDA_ASSERT(returnExpression); + ES2PANDA_ASSERT(returnExpression != nullptr); returnExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); } @@ -1844,7 +1847,7 @@ ir::Expression *ParserImpl::ParsePatternElement(ExpressionParseFlags flags, bool ir::Expression *rightNode = ParseExpression(); auto *assignmentExpression = AllocNode( ir::AstNodeType::ASSIGNMENT_PATTERN, returnNode, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); - ES2PANDA_ASSERT(assignmentExpression); + ES2PANDA_ASSERT(assignmentExpression != nullptr); assignmentExpression->SetRange({returnNode->Start(), rightNode->End()}); return assignmentExpression; @@ -1951,7 +1954,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta const util::StringView &ident = lexer_->GetToken().Ident(); auto *key = AllocNode(ident, Allocator()); - ES2PANDA_ASSERT(key); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); ir::Expression *value = AllocNode(ident, Allocator()); @@ -1969,6 +1972,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta auto *assignmentExpression = AllocNode( ir::AstNodeType::ASSIGNMENT_PATTERN, value, rightNode, lexer::TokenType::PUNCTUATOR_SUBSTITUTION); + ES2PANDA_ASSERT(assignmentExpression != nullptr); assignmentExpression->SetRange({value->Start(), rightNode->End()}); end = rightNode->End(); value = assignmentExpression; @@ -1978,7 +1982,7 @@ ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *sta } auto *returnProperty = AllocNode(key, value); - ES2PANDA_ASSERT(returnProperty); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); return returnProperty; @@ -2045,7 +2049,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_IDENT: { const util::StringView &ident = lexer_->GetToken().Ident(); key = AllocNode(ident, Allocator()); - ES2PANDA_ASSERT(key); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2053,7 +2057,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) case lexer::TokenType::LITERAL_STRING: { const util::StringView &string = lexer_->GetToken().String(); key = AllocNode(string); - ES2PANDA_ASSERT(key); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2064,7 +2068,7 @@ ir::Expression *ParserImpl::ParsePropertyKey(ExpressionParseFlags flags) } else { key = AllocNode(lexer_->GetToken().GetNumber()); } - ES2PANDA_ASSERT(key); + ES2PANDA_ASSERT(key != nullptr); key->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return key; @@ -2130,12 +2134,13 @@ ir::Expression *ParserImpl::ParsePropertyValue(const ir::PropertyKind *propertyK } ir::ScriptFunction *methodDefinitonNode = ParseFunction(newStatus); + ES2PANDA_ASSERT(methodDefinitonNode != nullptr); methodDefinitonNode->AddFlag(ir::ScriptFunctionFlags::METHOD); size_t paramsSize = methodDefinitonNode->Params().size(); auto *value = AllocNode(methodDefinitonNode); - ES2PANDA_ASSERT(value); + ES2PANDA_ASSERT(value != nullptr); value->SetRange(methodDefinitonNode->Range()); if (*propertyKind == ir::PropertyKind::SET && paramsSize != 1) { @@ -2185,12 +2190,12 @@ ir::Expression *ParserImpl::ParsePropertyDefinition([[maybe_unused]] ExpressionP } ir::Expression *value = ParsePropertyValue(&propertyKind, &methodStatus, flags); - ES2PANDA_ASSERT(value); + ES2PANDA_ASSERT(value != nullptr); lexer::SourcePosition end = value->End(); auto *returnProperty = AllocNode(propertyKind, key, value, methodStatus != ParserStatus::NO_OPTS, isComputed); - ES2PANDA_ASSERT(returnProperty); + ES2PANDA_ASSERT(returnProperty != nullptr); returnProperty->SetRange({start, end}); return returnProperty; @@ -2266,7 +2271,7 @@ ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags fla auto nodeType = inPattern ? ir::AstNodeType::OBJECT_PATTERN : ir::AstNodeType::OBJECT_EXPRESSION; auto *objectExpression = AllocNode(nodeType, Allocator(), std::move(properties), trailingComma); - ES2PANDA_ASSERT(objectExpression); + ES2PANDA_ASSERT(objectExpression != nullptr); objectExpression->SetRange({start, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -2313,7 +2318,7 @@ ir::SequenceExpression *ParserImpl::ParseSequenceExpression(ir::Expression *star lexer::SourcePosition end = sequence.back()->End(); auto *sequenceNode = AllocNode(std::move(sequence)); - ES2PANDA_ASSERT(sequenceNode); + ES2PANDA_ASSERT(sequenceNode != nullptr); sequenceNode->SetRange({start, end}); return sequenceNode; @@ -2405,7 +2410,7 @@ ir::Expression *ParserImpl::ParseImportExpression() } auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::IMPORT_META); - ES2PANDA_ASSERT(metaProperty); + ES2PANDA_ASSERT(metaProperty != nullptr); metaProperty->SetRange({startLoc, endLoc}); lexer_->NextToken(); @@ -2458,7 +2463,7 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat functionNode->SetStart(startLoc); auto *funcExpr = AllocNode(ident, functionNode); - ES2PANDA_ASSERT(funcExpr); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(functionNode->Range()); return funcExpr; diff --git a/ets2panda/parser/expressionTSParser.cpp b/ets2panda/parser/expressionTSParser.cpp index fe80a876b9..fc615e5bff 100644 --- a/ets2panda/parser/expressionTSParser.cpp +++ b/ets2panda/parser/expressionTSParser.cpp @@ -137,7 +137,7 @@ ir::Expression *TSParser::ParsePotentialAsExpression(ir::Expression *expr) lexer::SourcePosition startLoc = expr->Start(); auto *asExpr = AllocNode(expr, typeAnnotation, isConst); - ES2PANDA_ASSERT(asExpr); + ES2PANDA_ASSERT(asExpr != nullptr); asExpr->SetRange({startLoc, Lexer()->GetToken().End()}); if (Lexer()->GetToken().KeywordType() == lexer::TokenType::KEYW_AS) { @@ -170,7 +170,7 @@ ir::AnnotatedExpression *TSParser::ParsePatternElementGetReturnNode(ExpressionPa } case lexer::TokenType::LITERAL_IDENT: { ir::AnnotatedExpression *returnNode = AllocNode(Lexer()->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(returnNode); + ES2PANDA_ASSERT(returnNode != nullptr); if (returnNode->AsIdentifier()->Decorators().empty()) { returnNode->SetRange(Lexer()->GetToken().Loc()); @@ -330,6 +330,7 @@ ir::Expression *TSParser::ParseModuleReference() } result = AllocNode(Lexer()->GetToken().String()); + ES2PANDA_ASSERT(result != nullptr); result->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -342,7 +343,7 @@ ir::Expression *TSParser::ParseModuleReference() Lexer()->NextToken(); // eat ')' } else { result = AllocNode(Lexer()->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(result); + ES2PANDA_ASSERT(result != nullptr); result->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); @@ -357,6 +358,7 @@ ir::Expression *TSParser::ParseModuleReference() ir::TSTypeReference *TSParser::ParseConstExpression() { auto *identRef = AllocNode(Lexer()->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(identRef != nullptr); identRef->SetRange(Lexer()->GetToken().Loc()); auto *typeReference = AllocNode(identRef, nullptr, Allocator()); @@ -383,7 +385,7 @@ bool TSParser::ParsePotentialNonNullExpression(ir::Expression **returnExpression } *returnExpression = AllocNode(*returnExpression); - ES2PANDA_ASSERT(*returnExpression); + ES2PANDA_ASSERT(*returnExpression != nullptr); // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) (*returnExpression)->SetRange({startLoc, Lexer()->GetToken().End()}); Lexer()->NextToken(); @@ -451,7 +453,7 @@ ir::ArrowFunctionExpression *TSParser::ParsePotentialArrowExpression(ir::Express switch (Lexer()->GetToken().Type()) { case lexer::TokenType::KEYW_FUNCTION: { *returnExpression = ParseFunctionExpression(ParserStatus::ASYNC_FUNCTION); - ES2PANDA_ASSERT(*returnExpression); + ES2PANDA_ASSERT(*returnExpression != nullptr); (*returnExpression)->SetStart(startLoc); break; } diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 47b031611b..517290b9bf 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -84,7 +84,7 @@ void ParserImpl::ParseProgram(ScriptKind kind) auto statements = ParseStatementList(StatementParsingFlags::STMT_GLOBAL_LEXICAL); auto *blockStmt = AllocNode(Allocator(), std::move(statements)); - ES2PANDA_ASSERT(blockStmt); + ES2PANDA_ASSERT(blockStmt != nullptr); blockStmt->SetRange({startLoc, lexer_->GetToken().End()}); program_->SetAst(blockStmt); @@ -354,6 +354,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) ValidateClassKey(desc); propName = AllocNode(lexer_->GetToken().Ident(), Allocator()); + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); propName->AsIdentifier()->SetPrivate(desc->isPrivateIdent); break; @@ -370,6 +371,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) } propName = AllocNode(lexer_->GetToken().String()); + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); break; } @@ -381,7 +383,7 @@ ir::Expression *ParserImpl::ParseClassKey(ClassElementDescriptor *desc) } else { propName = AllocNode(lexer_->GetToken().GetNumber()); } - ES2PANDA_ASSERT(propName); + ES2PANDA_ASSERT(propName != nullptr); propName->SetRange(lexer_->GetToken().Loc()); break; @@ -461,7 +463,7 @@ ir::MethodDefinition *ParserImpl::ParseClassMethod(ClassElementDescriptor *desc, ir::ScriptFunction *func = ParseFunction(desc->newStatus); auto *funcExpr = AllocNode(func); - ES2PANDA_ASSERT(funcExpr); + ES2PANDA_ASSERT(funcExpr != nullptr); funcExpr->SetRange(func->Range()); if (desc->methodKind == ir::MethodDefinitionKind::SET) { @@ -487,7 +489,7 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, const ArenaVector &properties, ir::Expression *propName, ir::TypeNode *typeAnnotation) { - ES2PANDA_ASSERT(propName); + ES2PANDA_ASSERT(propName != nullptr); lexer::SourcePosition propEnd = propName->End(); ir::ClassElement *property = nullptr; @@ -595,7 +597,7 @@ ir::ClassElement *ParserImpl::ParseClassStaticBlock() auto *funcExpr = AllocNode(func); auto *staticBlock = AllocNode(funcExpr, Allocator()); - ES2PANDA_ASSERT(staticBlock); + ES2PANDA_ASSERT(staticBlock != nullptr); staticBlock->SetRange({startPos, lexer_->GetToken().End()}); lexer_->NextToken(); // eat '}' @@ -692,7 +694,7 @@ ir::MethodDefinition *ParserImpl::BuildImplicitConstructor(ir::ClassDefinitionMo auto *ctor = AllocNode(ir::MethodDefinitionKind::CONSTRUCTOR, key, funcExpr, ir::ModifierFlags::CONSTRUCTOR, Allocator(), false); - ES2PANDA_ASSERT(ctor); + ES2PANDA_ASSERT(ctor != nullptr); const auto rangeImplicitContstuctor = lexer::SourceRange(startLoc, startLoc); ctor->IterateRecursively( @@ -713,7 +715,7 @@ void ParserImpl::CreateImplicitConstructor(ir::MethodDefinition *&ctor, ctor = BuildImplicitConstructor(modifiers, startLoc); if ((flags & ir::ModifierFlags::DECLARE) != 0) { auto *ctorFunc = ctor->Function(); - ES2PANDA_ASSERT(ctorFunc); + ES2PANDA_ASSERT(ctorFunc != nullptr); ctorFunc->AddFlag(ir::ScriptFunctionFlags::EXTERNAL); } } @@ -800,7 +802,7 @@ ir::ClassDefinition *ParserImpl::ParseClassDefinition(ir::ClassDefinitionModifie auto *classDefinition = AllocNode(identNode, nullptr, superTypeParams, std::move(implements), ctor, superClass, std::move(properties), modifiers, flags, GetContext().GetLanguage()); - ES2PANDA_ASSERT(classDefinition); + ES2PANDA_ASSERT(classDefinition != nullptr); classDefinition->SetInternalName(privateBinding.View()); classDefinition->SetRange(bodyRange); @@ -960,7 +962,7 @@ std::tuple ParserImpl:: } ir::BlockStatement *body = ParseBlockStatement(); - ES2PANDA_ASSERT(body); + ES2PANDA_ASSERT(body != nullptr); return {true, body, body->End(), false}; } @@ -1024,7 +1026,7 @@ ir::ScriptFunction *ParserImpl::ParseFunction(ParserStatus newStatus) functionContext.Flags(), // CC-OFFNXT(G.FMT.02-CPP) project code style {}, // CC-OFFNXT(G.FMT.02-CPP) project code style context_.GetLanguage()}); // CC-OFF(G.FMT.02-CPP) project code style - ES2PANDA_ASSERT(funcNode); + ES2PANDA_ASSERT(funcNode != nullptr); funcNode->SetRange({startLoc, endLoc}); @@ -1054,7 +1056,7 @@ ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags) auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT; auto *spreadElementNode = AllocNode(nodeType, Allocator(), argument); - ES2PANDA_ASSERT(spreadElementNode); + ES2PANDA_ASSERT(spreadElementNode != nullptr); spreadElementNode->SetRange({startLocation, argument->End()}); return spreadElementNode; } @@ -1300,7 +1302,7 @@ ir::Identifier *ParserImpl::ExpectIdentifier([[maybe_unused]] bool isReference, } auto *ident = AllocNode(tokenName, Allocator()); - ES2PANDA_ASSERT(ident); + ES2PANDA_ASSERT(ident != nullptr); // NOTE: here actual token can be changed! ident->SetRange({tokenStart, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -1476,7 +1478,7 @@ ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourcePosition &p ir::Identifier *ParserImpl::AllocBrokenExpression(const lexer::SourceRange &range) { auto *node = AllocNode(Allocator()); - ES2PANDA_ASSERT(node); + ES2PANDA_ASSERT(node != nullptr); node->SetRange(range); return node; } @@ -1489,7 +1491,7 @@ ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourcePosition &pos) ir::TypeNode *ParserImpl::AllocBrokenType(const lexer::SourceRange &range) { auto node = AllocNode(Allocator()); - ES2PANDA_ASSERT(node); + ES2PANDA_ASSERT(node != nullptr); node->SetRange(range); return node; } diff --git a/ets2panda/parser/program/program.cpp b/ets2panda/parser/program/program.cpp index 9da4cfb1f6..f3efae5f7b 100644 --- a/ets2panda/parser/program/program.cpp +++ b/ets2panda/parser/program/program.cpp @@ -132,7 +132,7 @@ void Program::SetPackageInfo(const util::StringView &name, util::ModuleKind kind // NOTE(vpukhov): part of ongoing design void Program::MaybeTransformToDeclarationModule() { - ES2PANDA_ASSERT(ast_); + ES2PANDA_ASSERT(ast_ != nullptr); if (IsPackage() || ast_->Statements().empty()) { return; } diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index 756ce32cc8..ed69b3e589 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -230,7 +230,7 @@ ir::Statement *ParserImpl::ParseLetStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::LET); - ES2PANDA_ASSERT(variableDecl); + ES2PANDA_ASSERT(variableDecl != nullptr); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -249,7 +249,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) lexer_->NextToken(); auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); - ES2PANDA_ASSERT(variableDecl); + ES2PANDA_ASSERT(variableDecl != nullptr); if (variableDecl->IsBrokenStatement()) { // Error processing. return variableDecl; } @@ -263,7 +263,7 @@ ir::Statement *ParserImpl::ParseConstStatement(StatementParsingFlags flags) ir::EmptyStatement *ParserImpl::ParseEmptyStatement() { auto *empty = AllocNode(); - ES2PANDA_ASSERT(empty); + ES2PANDA_ASSERT(empty != nullptr); empty->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); return empty; @@ -272,7 +272,7 @@ ir::EmptyStatement *ParserImpl::ParseEmptyStatement() ir::Statement *ParserImpl::ParseDebuggerStatement() { auto *debuggerNode = AllocNode(); - ES2PANDA_ASSERT(debuggerNode); + ES2PANDA_ASSERT(debuggerNode != nullptr); debuggerNode->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); ConsumeSemicolon(debuggerNode); @@ -292,7 +292,7 @@ ir::Statement *ParserImpl::ParseFunctionStatement(StatementParsingFlags flags) stmts.push_back(funcDecl); auto *localBlockStmt = AllocNode(Allocator(), std::move(stmts)); - ES2PANDA_ASSERT(localBlockStmt); + ES2PANDA_ASSERT(localBlockStmt != nullptr); localBlockStmt->SetRange(funcDecl->Range()); return funcDecl; @@ -338,7 +338,7 @@ ir::Statement *ParserImpl::ParseStructDeclaration(ir::ClassDefinitionModifiers m lexer::SourcePosition endLoc = classDefinition->End(); auto *structDecl = AllocNode(classDefinition, Allocator()); - ES2PANDA_ASSERT(structDecl); + ES2PANDA_ASSERT(structDecl != nullptr); structDecl->SetRange({startLoc, endLoc}); return structDecl; } @@ -359,7 +359,7 @@ ir::Statement *ParserImpl::ParseClassDeclaration(ir::ClassDefinitionModifiers mo lexer::SourcePosition endLoc = classDefinition->End(); auto *classDecl = AllocNode(classDefinition, Allocator()); - ES2PANDA_ASSERT(classDecl); + ES2PANDA_ASSERT(classDecl != nullptr); classDecl->SetRange({startLoc, endLoc}); return classDecl; } @@ -386,7 +386,7 @@ void ParserImpl::ConsumeSemicolon(ir::Statement *statement) auto const &token = lexer_->GetToken(); auto tokenType = token.Type(); if (tokenType == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { - ES2PANDA_ASSERT(statement); + ES2PANDA_ASSERT(statement != nullptr); statement->SetEnd(token.End()); lexer_->NextToken(); return; @@ -442,7 +442,7 @@ bool ParserImpl::ParseDirective(ArenaVector *statements) bool isDirective = exprNode->IsStringLiteral(); auto *exprStatement = AllocNode(exprNode); - ES2PANDA_ASSERT(exprStatement); + ES2PANDA_ASSERT(exprStatement != nullptr); exprStatement->SetRange(exprNode->Range()); ConsumeSemicolon(exprStatement); @@ -473,7 +473,7 @@ ir::BlockStatement *ParserImpl::ParseBlockStatement() auto statements = ParseStatementList(); auto *blockNode = AllocNode(Allocator(), std::move(statements)); - ES2PANDA_ASSERT(blockNode); + ES2PANDA_ASSERT(blockNode != nullptr); blockNode->SetRange({startLoc, lexer_->GetToken().End()}); ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); @@ -505,7 +505,7 @@ ir::Statement *ParserImpl::ParseBreakStatement() } auto *breakStatement = AllocNode(); - ES2PANDA_ASSERT(breakStatement); + ES2PANDA_ASSERT(breakStatement != nullptr); breakStatement->SetRange({startLoc, lexer_->GetToken().End()}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -556,6 +556,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { auto *continueStatement = AllocNode(); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); return continueStatement; @@ -564,6 +565,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() if (lexer_->GetToken().NewLine() || lexer_->GetToken().Type() == lexer::TokenType::EOS || lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { auto *continueStatement = AllocNode(); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, endLoc}); return continueStatement; } @@ -581,7 +583,7 @@ ir::Statement *ParserImpl::ParseContinueStatement() identNode->SetRange(lexer_->GetToken().Loc()); auto *continueStatement = AllocNode(identNode); - ES2PANDA_ASSERT(continueStatement); + ES2PANDA_ASSERT(continueStatement != nullptr); continueStatement->SetRange({startLoc, lexer_->GetToken().End()}); lexer_->NextToken(); @@ -630,7 +632,7 @@ ir::Statement *ParserImpl::ParseDoWhileStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_PARENTHESIS); auto *doWhileStatement = AllocNode(body, condition); - ES2PANDA_ASSERT(doWhileStatement); + ES2PANDA_ASSERT(doWhileStatement != nullptr); doWhileStatement->SetRange({startLoc, endLoc}); if (lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_SEMI_COLON) { @@ -677,7 +679,7 @@ ir::FunctionDeclaration *ParserImpl::ParseFunctionDeclaration(bool canBeAnonymou newStatus |= ParserStatus::FUNCTION_DECLARATION; ir::ScriptFunction *func = ParseFunction(newStatus | ParserStatus::NEED_RETURN_TYPE); - ES2PANDA_ASSERT(func); + ES2PANDA_ASSERT(func != nullptr); func->SetIdent(identNode); func->SetStart(startLoc); @@ -740,7 +742,7 @@ ir::Statement *ParserImpl::ParseExpressionStatement(StatementParsingFlags flags) lexer::SourcePosition endPos = exprNode->End(); auto *exprStatementNode = AllocNode(exprNode); - ES2PANDA_ASSERT(exprStatementNode); + ES2PANDA_ASSERT(exprStatementNode != nullptr); exprStatementNode->SetRange({startPos.GetToken().Start(), endPos}); ConsumeSemicolon(exprStatementNode); @@ -871,7 +873,7 @@ std::tuple ir::AstNode *initNode = lexer_->GetToken().Type() == lexer::TokenType::PUNCTUATOR_COMMA ? ParseSequenceExpression(expr) : expr; - ES2PANDA_ASSERT(initNode); + ES2PANDA_ASSERT(initNode != nullptr); if (initNode->IsConditionalExpression()) { ir::ConditionalExpression *condExpr = initNode->AsConditionalExpression(); @@ -1024,7 +1026,7 @@ ir::Statement *ParserImpl::CreateForStatement(ForStatementNodes &&nodes, ForStat } } - ES2PANDA_ASSERT(forStatement); + ES2PANDA_ASSERT(forStatement != nullptr); forStatement->SetRange({startLoc, nodes.body->End()}); return forStatement; @@ -1102,7 +1104,7 @@ ir::Statement *ParserImpl::ParseIfStatement() } auto *ifStatement = AllocNode(test, consequent, alternate); - ES2PANDA_ASSERT(ifStatement); + ES2PANDA_ASSERT(ifStatement != nullptr); ifStatement->SetRange({startLoc, endLoc}); return ifStatement; } @@ -1122,6 +1124,7 @@ ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &po SavedParserContext newCtx(this, ParserStatus::IN_LABELED, actualLabel); auto *identNode = AllocNode(actualLabel, Allocator()); + ES2PANDA_ASSERT(identNode != nullptr); identNode->SetRange(pos.GetToken().Loc()); lexer_->NextToken(); @@ -1133,7 +1136,7 @@ ir::Statement *ParserImpl::ParseLabelledStatement(const lexer::LexerPosition &po ir::Statement *body = ParseStatement(StatementParsingFlags::LABELLED); auto *labeledStatement = AllocNode(identNode, body); - ES2PANDA_ASSERT(labeledStatement); + ES2PANDA_ASSERT(labeledStatement != nullptr); labeledStatement->SetRange({pos.GetToken().Start(), body->End()}); return labeledStatement; @@ -1173,7 +1176,7 @@ ir::Statement *ParserImpl::ParseReturnStatement() returnStatement = AllocNode(); } - ES2PANDA_ASSERT(returnStatement); + ES2PANDA_ASSERT(returnStatement != nullptr); returnStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(returnStatement); @@ -1229,7 +1232,7 @@ ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault) } auto *caseNode = AllocNode(testExpr, std::move(consequents)); - ES2PANDA_ASSERT(caseNode); + ES2PANDA_ASSERT(caseNode != nullptr); caseNode->SetRange({caseStartLoc, caseEndLoc}); return caseNode; } @@ -1261,7 +1264,7 @@ ir::Statement *ParserImpl::ParseSwitchStatement() ExpectToken(lexer::TokenType::PUNCTUATOR_RIGHT_BRACE); auto *switchStatement = AllocNode(discriminant, std::move(cases)); - ES2PANDA_ASSERT(switchStatement); + ES2PANDA_ASSERT(switchStatement != nullptr); switchStatement->SetRange({startLoc, endLoc}); return switchStatement; } @@ -1286,7 +1289,7 @@ ir::Statement *ParserImpl::ParseThrowStatement() lexer::SourcePosition endLoc = expression->End(); auto *throwStatement = AllocNode(expression); - ES2PANDA_ASSERT(throwStatement); + ES2PANDA_ASSERT(throwStatement != nullptr); throwStatement->SetRange({startLoc, endLoc}); ConsumeSemicolon(throwStatement); @@ -1338,10 +1341,11 @@ ir::CatchClause *ParserImpl::ParseCatchClause() } ir::BlockStatement *catchBlock = ParseBlockStatement(); + ES2PANDA_ASSERT(catchBlock != nullptr); lexer::SourcePosition endLoc = catchBlock->End(); auto *catchClause = AllocNode(param, catchBlock); - ES2PANDA_ASSERT(catchClause); + ES2PANDA_ASSERT(catchClause != nullptr); catchClause->SetRange({catchStartLoc, endLoc}); return catchClause; @@ -1386,7 +1390,7 @@ ir::Statement *ParserImpl::ParseTryStatement() lexer_->NextToken(); // eat 'finally' keyword finallyClause = ParseBlockStatement(); - ES2PANDA_ASSERT(finallyClause); + ES2PANDA_ASSERT(finallyClause != nullptr); endLoc = finallyClause->End(); } @@ -1557,7 +1561,7 @@ ir::Statement *ParserImpl::ParseVariableDeclaration(VariableParsingFlags flags) lexer::SourcePosition endLoc = declarators.back()->End(); auto *declaration = AllocNode(varKind, Allocator(), std::move(declarators)); - ES2PANDA_ASSERT(declaration); + ES2PANDA_ASSERT(declaration != nullptr); declaration->SetRange({startLoc, endLoc}); return declaration; @@ -1585,7 +1589,7 @@ ir::Statement *ParserImpl::ParseWhileStatement() lexer::SourcePosition endLoc = body->End(); auto *whileStatement = AllocNode(condition, body); - ES2PANDA_ASSERT(whileStatement); + ES2PANDA_ASSERT(whileStatement != nullptr); whileStatement->SetRange({startLoc, endLoc}); return whileStatement; @@ -1636,7 +1640,7 @@ ir::ExportDefaultDeclaration *ParserImpl::ParseExportDefaultDeclaration(const le ES2PANDA_ASSERT(declNode != nullptr); lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -1660,7 +1664,7 @@ ir::Identifier *ParserImpl::ParseNamedExport(lexer::Token *exportedToken) const util::StringView &exportedString = exportedToken->Ident(); auto *exported = AllocNode(exportedString, Allocator()); - ES2PANDA_ASSERT(exported); + ES2PANDA_ASSERT(exported != nullptr); exported->SetRange(exportedToken->Loc()); return exported; @@ -1678,11 +1682,11 @@ ir::ExportAllDeclaration *ParserImpl::ParseExportAllDeclaration(const lexer::Sou lexer_->NextToken(); // eat exported name } ir::StringLiteral *source = ParseFromClause(); - ES2PANDA_ASSERT(source); + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *exportDeclaration = AllocNode(source, exported); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(exportDeclaration); @@ -1737,7 +1741,7 @@ ir::ExportNamedDeclaration *ParserImpl::ParseExportNamedSpecifiers(const lexer:: } auto *exportDeclaration = AllocNode(Allocator(), source, std::move(specifiers)); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endPos}); ConsumeSemicolon(exportDeclaration); @@ -1792,7 +1796,7 @@ ir::Statement *ParserImpl::ParseNamedExportDeclaration(const lexer::SourcePositi lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -1841,7 +1845,7 @@ void ParserImpl::ParseNameSpaceImport(ArenaVector *specifiers) ir::Identifier *local = ParseNamedImport(&lexer_->GetToken()); auto *specifier = AllocNode(local); - ES2PANDA_ASSERT(specifier); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange({namespaceStart, lexer_->GetToken().End()}); specifiers->push_back(specifier); @@ -1859,7 +1863,7 @@ ir::Identifier *ParserImpl::ParseNamedImport(lexer::Token *importedToken) CheckRestrictedBinding(importedToken->KeywordType()); auto *local = AllocNode(importedToken->Ident(), Allocator()); - ES2PANDA_ASSERT(local); + ES2PANDA_ASSERT(local != nullptr); local->SetRange(importedToken->Loc()); return local; @@ -1906,7 +1910,7 @@ ir::AstNode *ParserImpl::ParseImportDefaultSpecifier(ArenaVector lexer_->NextToken(); // eat local name auto *specifier = AllocNode(local); - ES2PANDA_ASSERT(specifier); + ES2PANDA_ASSERT(specifier != nullptr); specifier->SetRange(specifier->Local()->Range()); specifiers->push_back(specifier); @@ -1939,7 +1943,7 @@ ir::StringLiteral *ParserImpl::ParseFromClause(bool requireFrom) } auto *source = AllocNode(lexer_->GetToken().String()); - ES2PANDA_ASSERT(source); + ES2PANDA_ASSERT(source != nullptr); source->SetRange(lexer_->GetToken().Loc()); lexer_->NextToken(); @@ -1998,7 +2002,7 @@ ir::Statement *ParserImpl::ParseImportDeclaration(StatementParsingFlags flags) lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); - ES2PANDA_ASSERT(importDeclaration); + ES2PANDA_ASSERT(importDeclaration != nullptr); importDeclaration->SetRange({startLoc, endLoc}); ConsumeSemicolon(importDeclaration); @@ -2014,7 +2018,7 @@ ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourcePosition &pos ir::Statement *ParserImpl::AllocBrokenStatement(const lexer::SourceRange &range) { auto *broken = AllocNode(true); - ES2PANDA_ASSERT(broken); + ES2PANDA_ASSERT(broken != nullptr); broken->SetRange(range); return broken; } @@ -2030,7 +2034,7 @@ bool ParserImpl::IsBrokenStatement(ir::Statement *st) ir::Statement *ParserImpl::AllocEmptyStatement() { auto *empty = AllocNode(); - ES2PANDA_ASSERT(empty); + ES2PANDA_ASSERT(empty != nullptr); empty->SetRange(lexer_->GetToken().Loc()); return empty; } diff --git a/ets2panda/parser/statementTSParser.cpp b/ets2panda/parser/statementTSParser.cpp index 2a4840d461..4cd60c24db 100644 --- a/ets2panda/parser/statementTSParser.cpp +++ b/ets2panda/parser/statementTSParser.cpp @@ -131,7 +131,7 @@ ir::TSImportEqualsDeclaration *TSParser::ParseTsImportEqualsDeclaration(const le } auto *id = AllocNode(Lexer()->GetToken().Ident(), Allocator()); - ES2PANDA_ASSERT(id); + ES2PANDA_ASSERT(id != nullptr); id->SetRange(Lexer()->GetToken().Loc()); Lexer()->NextToken(); // eat id name @@ -191,7 +191,7 @@ ir::ExportDefaultDeclaration *TSParser::ParseExportDefaultDeclaration(const lexe lexer::SourcePosition endLoc = declNode->End(); auto *exportDeclaration = AllocNode(declNode, isExportEquals); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); if (eatSemicolon) { @@ -267,7 +267,7 @@ ir::Statement *TSParser::ParseNamedExportDeclaration(const lexer::SourcePosition lexer::SourcePosition endLoc = decl->End(); ArenaVector specifiers(Allocator()->Adapter()); auto *exportDeclaration = AllocNode(Allocator(), decl, std::move(specifiers)); - ES2PANDA_ASSERT(exportDeclaration); + ES2PANDA_ASSERT(exportDeclaration != nullptr); exportDeclaration->SetRange({startLoc, endLoc}); return exportDeclaration; @@ -296,7 +296,7 @@ ir::Statement *TSParser::ParseExportDeclaration(StatementParsingFlags flags) } default: { auto ret = ParseNamedExportDeclaration(startLoc); - ES2PANDA_ASSERT(ret); + ES2PANDA_ASSERT(ret != nullptr); if (ret->IsBrokenStatement()) { return ret; } @@ -326,7 +326,7 @@ ir::Statement *TSParser::ParseConstStatement(StatementParsingFlags flags) } auto *variableDecl = ParseVariableDeclaration(VariableParsingFlags::CONST | VariableParsingFlags::NO_SKIP_VAR_KIND); - ES2PANDA_ASSERT(variableDecl); + ES2PANDA_ASSERT(variableDecl != nullptr); variableDecl->SetStart(constVarStar); ConsumeSemicolon(variableDecl); @@ -369,7 +369,7 @@ ir::Statement *TSParser::ParseImportDeclaration([[maybe_unused]] StatementParsin source = ParseFromClause(false); } - ES2PANDA_ASSERT(source); + ES2PANDA_ASSERT(source != nullptr); lexer::SourcePosition endLoc = source->End(); auto *importDeclaration = AllocNode(source, std::move(specifiers)); importDeclaration->SetRange({startLoc, endLoc}); -- Gitee From 9cfe3c52bee170aa80b2db1d16f063407391269b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=92=9F=E6=9F=A0?= Date: Mon, 7 Jul 2025 17:09:34 +0800 Subject: [PATCH 062/107] fix issue for sdk-limited-void-type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKE62 Test scenarios: sdk-limited-void-type Signed-off-by: 钟柠 --- ets2panda/linter/src/lib/TypeScriptLinter.ts | 17 ++++++++ .../test/sdkwhite/limit_void_type_sdk2.ets | 12 +++++- .../limit_void_type_sdk2.ets.arkts2.json | 40 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..d0f83da321 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -8020,6 +8020,9 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (!setApiListItem) { return; } + if (TypeScriptLinter.isInterfaceImplementation(errorNode)) { + return; + } const apiNamesArr = [...setApiListItem]; const hasSameApiName = apiNamesArr.some((apilistItem) => { return apilistItem.api_info.api_name === errorNode.getText(); @@ -8049,6 +8052,20 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } } + static isInterfaceImplementation(node: ts.Node): boolean { + const classDeclaration = ts.findAncestor(node, ts.isClassDeclaration); + if (!classDeclaration) { + return false; + } + + if (classDeclaration.heritageClauses) { + return classDeclaration.heritageClauses.some((clause) => { + return clause.token === ts.SyntaxKind.ImplementsKeyword; + }); + } + return false; + } + private isIdentifierFromSDK(node: ts.Node): boolean { const symbol = this.tsTypeChecker.getSymbolAtLocation(node); if (!symbol) { diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets index 4592f1a479..5eca858a48 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets @@ -58,4 +58,14 @@ function prefetchTest2(){ } export const res = new MyDataSource().cancel(222); //report error -export const res2 = ds.cancel(222); //report error \ No newline at end of file +export const res2 = ds.cancel(222); //report error + +interface BackPressInterceptor { + onBackPress: ()=> boolean | void; +} + +class A implements BackPressInterceptor{ + onBackPress() : boolean | void { + return false; + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json index 646d8423c0..e4787f158f 100644 --- a/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json +++ b/ets2panda/linter/test/sdkwhite/limit_void_type_sdk2.ets.arkts2.json @@ -204,6 +204,46 @@ "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", "severity": "ERROR" }, + { + "line": 68, + "column": 3, + "endLine": 70, + "endColumn": 4, + "problem": "MethodOverridingField", + "suggest": "", + "rule": "Method can't override filed in interface implemented (arkts-no-method-overriding-field)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 31, + "endLine": 64, + "endColumn": 35, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 19, + "endLine": 68, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 29, + "endLine": 68, + "endColumn": 33, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, { "line": 44, "column": 41, -- Gitee From 72ac2683e7839345b5b979c30b7779c26468cb5b Mon Sep 17 00:00:00 2001 From: dogasahin Date: Tue, 8 Jul 2025 09:40:51 +0300 Subject: [PATCH 063/107] [LSPAPI] RemoveAccidentalCallParentheses Issue : https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJJQT Signed-off-by: dogasahin --- ets2panda/lsp/BUILD.gn | 1 + ets2panda/lsp/CMakeLists.txt | 1 + .../remove_accidental_call_parentheses.h | 41 +++++ .../remove_accidental_call_parentheses.cpp | 130 +++++++++++++++ .../services/text_change/change_tracker.cpp | 22 ++- ets2panda/test/unit/lsp/CMakeLists.txt | 4 + ...emove_accidental_call_parentheses_test.cpp | 148 ++++++++++++++++++ ets2panda/util/diagnostic/semantic.yaml | 1 + 8 files changed, 341 insertions(+), 7 deletions(-) create mode 100644 ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h create mode 100644 ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp create mode 100644 ets2panda/test/unit/lsp/remove_accidental_call_parentheses_test.cpp diff --git a/ets2panda/lsp/BUILD.gn b/ets2panda/lsp/BUILD.gn index fd60354d62..78dec71308 100644 --- a/ets2panda/lsp/BUILD.gn +++ b/ets2panda/lsp/BUILD.gn @@ -87,6 +87,7 @@ ohos_source_set("libes2panda_lsp_static") { "src/register_code_fix/fix_nan_equality.cpp", "src/register_code_fix/forgetten_this_property_access.cpp", "src/register_code_fix/import_fixes.cpp", + "src/register_code_fix/remove_accidental_call_parentheses.cpp", "src/rename.cpp", "src/register_code_fix/ui_plugin_suggest.cpp", "src/script_element_kind.cpp", diff --git a/ets2panda/lsp/CMakeLists.txt b/ets2panda/lsp/CMakeLists.txt index fe1c0fb756..bb3d59457c 100644 --- a/ets2panda/lsp/CMakeLists.txt +++ b/ets2panda/lsp/CMakeLists.txt @@ -117,6 +117,7 @@ set(ES2PANDA_LSP_SRC ./src/register_code_fix/fix_nan_equality.cpp ./src/register_code_fix/forgetten_this_property_access.cpp ./src/register_code_fix/import_fixes.cpp + ./src/register_code_fix/remove_accidental_call_parentheses.cpp ./src/register_code_fix/ui_plugin_suggest.cpp ./src/get_name_or_dotted_name_span.cpp ) diff --git a/ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h b/ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h new file mode 100644 index 0000000000..7775a44025 --- /dev/null +++ b/ets2panda/lsp/include/register_code_fix/remove_accidental_call_parentheses.h @@ -0,0 +1,41 @@ +/** + * 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. + */ + +#ifndef FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H +#define FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H + +#include +#include +#include "lsp/include/services/text_change/change_tracker.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/types.h" + +namespace ark::es2panda::lsp { + +class FixRemoveAccidentalCallParentheses : public CodeFixRegistration { +public: + FixRemoveAccidentalCallParentheses(); + std::vector GetCodeActions(const CodeFixContext &context) override; + CombinedCodeActions GetAllCodeActions(const CodeFixAllContext &codeFixAll) override; + static std::vector GetCodeActionsToFix(const CodeFixContext &context); + +private: + static void MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes); + bool static IsValidCallExpression(const ir::AstNode *node); + static TextRange CalculateDeleteRange(const ir::AstNode *callExpr); +}; +} // namespace ark::es2panda::lsp +#endif // FIX_REMOVE_ACCIDENTAL_CALL_PARENTHESES_H diff --git a/ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp b/ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp new file mode 100644 index 0000000000..7272cb01d5 --- /dev/null +++ b/ets2panda/lsp/src/register_code_fix/remove_accidental_call_parentheses.cpp @@ -0,0 +1,130 @@ +/** + * 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. + */ + +#include "lsp/include/internal_api.h" +#include "lsp/include/code_fix_provider.h" +#include "lsp/include/register_code_fix/remove_accidental_call_parentheses.h" + +namespace ark::es2panda::lsp { +const int G_REMOVE_CALL_PARENS_CODE = 1011; + +bool FixRemoveAccidentalCallParentheses::IsValidCallExpression(const ir::AstNode *node) +{ + if (node == nullptr || !node->IsCallExpression()) { + return false; + } + + const auto *callExpr = node->AsCallExpression(); + const auto *callee = callExpr->Callee(); + if (callee == nullptr) { + return false; + } + + if (!callee->IsMemberExpression()) { + return false; + } + + if (!callExpr->Arguments().empty()) { + return false; + } + + return true; +} + +TextRange FixRemoveAccidentalCallParentheses::CalculateDeleteRange(const ir::AstNode *callExpr) +{ + const auto *callExpression = callExpr->AsCallExpression(); + if (callExpression == nullptr || callExpression->Callee() == nullptr) { + return TextRange {0, 0}; + } + + size_t openParenPos = static_cast(callExpression->Callee()->End().index); + size_t closeParenPos = static_cast(callExpression->End().index); + if (closeParenPos <= openParenPos) { + return TextRange {0, 0}; + } + + return TextRange {openParenPos, closeParenPos}; +} + +void FixRemoveAccidentalCallParentheses::MakeChange(ChangeTracker &changeTracker, es2panda_Context *context, size_t pos, + std::vector &fixedNodes) +{ + auto *token = GetTouchingToken(context, pos, false); + if (token == nullptr) { + return; + } + + const ir::AstNode *callExpr = token; + while (callExpr != nullptr && !callExpr->IsCallExpression()) { + callExpr = callExpr->Parent(); + } + + if (!IsValidCallExpression(callExpr)) { + return; + } + + TextRange deleteRange = CalculateDeleteRange(callExpr); + if (deleteRange.pos == 0 && deleteRange.end == 0) { + return; + } + + fixedNodes.push_back(const_cast(callExpr)); + auto *ctx = reinterpret_cast(context); + const auto sourceFile = ctx->sourceFile; + changeTracker.DeleteRange(sourceFile, deleteRange); +} + +std::vector FixRemoveAccidentalCallParentheses::GetCodeActionsToFix(const CodeFixContext &context) +{ + TextChangesContext textChangesContext = {context.host, context.formatContext, context.preferences}; + std::vector fixedNodes; + auto fileTextChanges = ChangeTracker::With(textChangesContext, [&](ChangeTracker &tracker) { + MakeChange(tracker, context.context, context.span.start, fixedNodes); + }); + + return fileTextChanges; +} + +FixRemoveAccidentalCallParentheses::FixRemoveAccidentalCallParentheses() +{ + const char *fixId = "RemoveAccidentalCallParentheses"; + SetErrorCodes({G_REMOVE_CALL_PARENS_CODE}); + SetFixIds({fixId}); +} + +std::vector FixRemoveAccidentalCallParentheses::GetCodeActions(const CodeFixContext &context) +{ + std::vector returnedActions; + auto changes = GetCodeActionsToFix(context); + if (!changes.empty()) { + CodeFixAction codeAction; + codeAction.fixName = "removeAccidentalCallParentheses"; + codeAction.description = "Remove parentheses from accessor call"; + codeAction.changes = changes; + codeAction.fixId = "RemoveAccidentalCallParentheses"; + returnedActions.push_back(codeAction); + } + return returnedActions; +} + +CombinedCodeActions FixRemoveAccidentalCallParentheses::GetAllCodeActions(const CodeFixAllContext &codeFixAll) +{ + (void)codeFixAll; + return {}; +} +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects, cert-err58-cpp) +AutoCodeFixRegister g_removeCallParens("RemoveAccidentalCallParentheses"); +} // namespace ark::es2panda::lsp \ No newline at end of file diff --git a/ets2panda/lsp/src/services/text_change/change_tracker.cpp b/ets2panda/lsp/src/services/text_change/change_tracker.cpp index fd86706d03..949c7f1747 100644 --- a/ets2panda/lsp/src/services/text_change/change_tracker.cpp +++ b/ets2panda/lsp/src/services/text_change/change_tracker.cpp @@ -779,14 +779,22 @@ void ChangeTracker::InsertImportSpecifierAtIndex(es2panda_Context *context, ir:: std::vector ChangeTracker::GetTextChangesFromChanges(std::vector &changes) { std::unordered_map fileChangesMap; + auto addChange = [&](const SourceFile *sourceFile, TextRange range, const std::string &newText) { + const std::string filePath = std::string(sourceFile->filePath); + TextChange c = {{range.pos, range.end - range.pos}, newText}; + + auto &fileChange = fileChangesMap[filePath]; + if (fileChange.fileName.empty()) { + fileChange.fileName = filePath; + } + fileChange.textChanges.push_back(c); + }; + for (const auto &change : changes) { - if (const auto *textChange = std::get_if(&change)) { - TextChange c = {{textChange->range.pos, textChange->range.end - textChange->range.pos}, textChange->text}; - const std::string &filePath = std::string(textChange->sourceFile->filePath); - if (fileChangesMap.find(filePath) == fileChangesMap.end()) { - fileChangesMap[filePath].fileName = filePath; - } - fileChangesMap[filePath].textChanges.push_back(c); + if (const auto *textChange = std::get_if(&change)) { + addChange(textChange->sourceFile, textChange->range, textChange->text); + } else if (const auto *remove = std::get_if(&change)) { + addChange(remove->sourceFile, remove->range, ""); } } diff --git a/ets2panda/test/unit/lsp/CMakeLists.txt b/ets2panda/test/unit/lsp/CMakeLists.txt index e6b327c3fd..06df7356e7 100644 --- a/ets2panda/test/unit/lsp/CMakeLists.txt +++ b/ets2panda/test/unit/lsp/CMakeLists.txt @@ -258,3 +258,7 @@ ets2panda_add_gtest(lsp_api_test_get_name_or_dotted_name_span CPP_SOURCES ets2panda_add_gtest(lsp_api_test_fix_convert_const_to_let CPP_SOURCES fix_convert_const_to_let_test.cpp ) + + ets2panda_add_gtest(lsp_api_test_remove_accidental_call_parentheses CPP_SOURCES + remove_accidental_call_parentheses_test.cpp + ) \ No newline at end of file diff --git a/ets2panda/test/unit/lsp/remove_accidental_call_parentheses_test.cpp b/ets2panda/test/unit/lsp/remove_accidental_call_parentheses_test.cpp new file mode 100644 index 0000000000..8004de427d --- /dev/null +++ b/ets2panda/test/unit/lsp/remove_accidental_call_parentheses_test.cpp @@ -0,0 +1,148 @@ +/** + * 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. + */ + +#include "gtest/gtest.h" +#include "lsp/include/code_fixes/code_fix_types.h" +#include "lsp/include/register_code_fix/remove_accidental_call_parentheses.h" +#include "lsp/include/internal_api.h" +#include "public/es2panda_lib.h" +#include "lsp_api_test.h" + +namespace { +constexpr int DEFAULT_THROTTLE = 20; +const size_t GETTER_CALL_IDX = 92; +const size_t IGNORE_MALFORMED_CALL_IDX = 42; +const size_t NON_FUNC_CALLS_IDX = 83; +const size_t SKIP_VALID_METHOD_CALL_IDX = 77; + +class FixRemoveCallParensTests : public LSPAPITests { +public: + class NullCancellationToken : public ark::es2panda::lsp::HostCancellationToken { + public: + bool IsCancellationRequested() override + { + return false; + } + }; + + static ark::es2panda::lsp::CancellationToken CreateToken() + { + static NullCancellationToken nullToken; + return ark::es2panda::lsp::CancellationToken(DEFAULT_THROTTLE, &nullToken); + } + + static ark::es2panda::lsp::CodeFixContext CreateCodeFixContext(es2panda_Context *ctx, size_t pos) + { + ark::es2panda::lsp::RulesMap rules; + ark::es2panda::lsp::FormatCodeSettings formatSettings; + ark::es2panda::lsp::UserPreferences preferences; + LanguageServiceHost host; + ark::es2panda::lsp::FormatContext fmtCtx {formatSettings, rules}; + TextChangesContext textCtx {host, fmtCtx, preferences}; + return ark::es2panda::lsp::CodeFixContext {{textCtx, ctx, CreateToken()}, 0, TextSpan {pos, 0}}; + } +}; + +TEST_F(FixRemoveCallParensTests, RemovesParenthesesFromGetterCall) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +class Obj { + get value() { + return () => 42; + } +} +const obj = new Obj(); +const x = obj.value(); + )"; + + const auto c1 = 1; + const auto c2 = 2; + es2panda_Context *ctx = initializer.CreateContext("rmv_accidental_call_parens_getter_call.ets", + ES2PANDA_STATE_CHECKED, sourceCode.c_str()); + ark::es2panda::lsp::FixRemoveAccidentalCallParentheses fix; + ark::es2panda::lsp::CodeFixContext context = CreateCodeFixContext(ctx, GETTER_CALL_IDX); + auto actions = fix.GetCodeActions(context); + ASSERT_EQ(actions.size(), c1); + const auto &change = actions[0].changes[0].textChanges[0]; + EXPECT_EQ(change.newText, ""); + EXPECT_EQ(change.span.length, c2); + initializer.DestroyContext(ctx); +} + +TEST_F(FixRemoveCallParensTests, ignore_malformed_call_expressions) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +const obj = { value: 42 }; +const z = obj.value(; + )"; + + es2panda_Context *ctx = initializer.CreateContext("rmv_accidental_call_parens_mallformed_call_expr.ets", + ES2PANDA_STATE_CHECKED, sourceCode.c_str()); + ark::es2panda::lsp::FixRemoveAccidentalCallParentheses fix; + ark::es2panda::lsp::CodeFixContext context = CreateCodeFixContext(ctx, IGNORE_MALFORMED_CALL_IDX); + auto actions = fix.GetCodeActions(context); + EXPECT_TRUE(actions.empty()); + initializer.DestroyContext(ctx); +} + +TEST_F(FixRemoveCallParensTests, remove_parens_from_non_function_property_call) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +type MyObj = { + value: number; +}; +const obj: MyObj = { value: 5 }; +const z = obj.value() + )"; + + const auto c1 = 1; + const auto c2 = 2; + es2panda_Context *ctx = initializer.CreateContext("rmv_accidental_call_parens_nonfunc_propety_call.ets", + ES2PANDA_STATE_CHECKED, sourceCode.c_str()); + ark::es2panda::lsp::FixRemoveAccidentalCallParentheses fix; + ark::es2panda::lsp::CodeFixContext context = CreateCodeFixContext(ctx, NON_FUNC_CALLS_IDX); + auto actions = fix.GetCodeActions(context); + ASSERT_EQ(actions.size(), c1); + const auto &change = actions[0].changes[0].textChanges[0]; + EXPECT_EQ(change.newText, ""); + EXPECT_EQ(change.span.length, c2); + initializer.DestroyContext(ctx); +} + +TEST_F(FixRemoveCallParensTests, SkipsValidMethodCall) +{ + ark::es2panda::lsp::Initializer initializer; + const std::string sourceCode = R"( +class A { + calc(): number { + return 1; + } +} +const obj = new A(); +const y = obj.calc(); + )"; + + es2panda_Context *ctx = initializer.CreateContext("rmv_accidental_call_parens_valid_call.ets", + ES2PANDA_STATE_CHECKED, sourceCode.c_str()); + ark::es2panda::lsp::FixRemoveAccidentalCallParentheses fix; + ark::es2panda::lsp::CodeFixContext context = CreateCodeFixContext(ctx, SKIP_VALID_METHOD_CALL_IDX); + auto actions = fix.GetCodeActions(context); + EXPECT_TRUE(actions.empty()); + initializer.DestroyContext(ctx); +} +} // namespace \ No newline at end of file diff --git a/ets2panda/util/diagnostic/semantic.yaml b/ets2panda/util/diagnostic/semantic.yaml index 0def07ffc8..aad4b5292a 100644 --- a/ets2panda/util/diagnostic/semantic.yaml +++ b/ets2panda/util/diagnostic/semantic.yaml @@ -497,6 +497,7 @@ semantic: - name: EXTENSION_ACCESSOR_INVALID_CALL id: 59 message: "Extension accessor can't be used as a method call or function call." + code_fix_ids: [RemoveAccidetalCallParentheses] - name: EXTENSION_FUNC_NAME_CONFLICT_WITH_METH id: 81 -- Gitee From 91b7934e1afe37e385f6640f4641040b9eedbf40 Mon Sep 17 00:00:00 2001 From: Vivien Voros Date: Thu, 12 Jun 2025 18:12:41 +0200 Subject: [PATCH 064/107] Increasing coverage of diagnostic errors - 3 Add new tests to increase code coverage Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICFVER Related Internal Issue: #26188 Change-Id: I54500963da4906a9bb1782cfd88d4647937a2202 Signed-off-by: Vivien Voros --- ets2panda/parser/TypedParser.cpp | 8 -- ets2panda/parser/expressionParser.cpp | 15 +-- ets2panda/parser/parserImpl.cpp | 8 -- ets2panda/parser/parserImpl.h | 2 +- .../parser/ets/invalid_destructing_target.ets | 19 ++++ .../parser/js/static_property_prototype.js | 21 ++++ ets2panda/test/ast/parser/js/test_yield.js | 18 ++++ .../ast/parser/ts/test_class_constructor.ts | 20 ++++ .../ast/parser/ts/test_insufficient_param.ts | 18 ++++ .../ast/parser/ts/test_invalid_left_side.ts | 18 ++++ .../ast/parser/ts/test_rest_param_not_last.ts | 17 +++ .../ts/test_restparam_id_in_dec_context.ts | 18 ++++ .../ts/test_static_property_prototype.ts | 20 ++++ .../ast/parser/ts/test_unexpected_token.ts | 20 ++++ .../test/ast/parser/ts/test_yield_escaped.ts | 25 +++++ ets2panda/util/diagnostic/syntax.yaml | 100 ++++-------------- 16 files changed, 238 insertions(+), 109 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/invalid_destructing_target.ets create mode 100644 ets2panda/test/ast/parser/js/static_property_prototype.js create mode 100644 ets2panda/test/ast/parser/js/test_yield.js create mode 100644 ets2panda/test/ast/parser/ts/test_class_constructor.ts create mode 100644 ets2panda/test/ast/parser/ts/test_insufficient_param.ts create mode 100644 ets2panda/test/ast/parser/ts/test_invalid_left_side.ts create mode 100644 ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts create mode 100644 ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts create mode 100644 ets2panda/test/ast/parser/ts/test_static_property_prototype.ts create mode 100644 ets2panda/test/ast/parser/ts/test_unexpected_token.ts create mode 100644 ets2panda/test/ast/parser/ts/test_yield_escaped.ts diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index cc626c2ed9..6819c39b8b 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -1522,14 +1522,6 @@ ParserStatus TypedParser::ValidateArrowParameter(ir::Expression *expr, bool *see [[fallthrough]]; } - case ir::AstNodeType::REST_ELEMENT: { - if (expr->AsRestElement()->IsOptional()) { - LogError(diagnostic::REST_PARAM_CANNOT_BE_OPTIONAL, {}, expr->Start()); - } - - ValidateArrowParameterBindings(expr->AsRestElement()->Argument()); - return ParserStatus::HAS_COMPLEX_PARAM; - } case ir::AstNodeType::IDENTIFIER: { const util::StringView &identifier = expr->AsIdentifier()->Name(); bool isOptional = expr->AsIdentifier()->IsOptional(); diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 24a4b657b3..9e4eee3a6e 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -855,10 +855,6 @@ ir::MetaProperty *ParserImpl::ParsePotentialNewTarget() LogError(diagnostic::NEW_TARGET_IS_NOT_ALLOWED); } - if ((lexer_->GetToken().Flags() & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::NEW_TARGET_WITH_ESCAPED_CHARS); - } - auto *metaProperty = AllocNode(ir::MetaProperty::MetaPropertyKind::NEW_TARGET); ES2PANDA_ASSERT(metaProperty); metaProperty->SetRange(loc); @@ -1920,15 +1916,11 @@ static bool IsShorthandDelimiter(char32_t cp) } } -void ParserImpl::ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags) +void ParserImpl::ValidateAccessor(ExpressionParseFlags flags) { if ((flags & ExpressionParseFlags::MUST_BE_PATTERN) != 0) { LogError(diagnostic::UNEXPECTED_TOKEN); } - - if ((currentTokenFlags & lexer::TokenFlags::HAS_ESCAPE) != 0) { - LogError(diagnostic::KEYWORD_CONTAINS_ESCAPED_CHARS); - } } ir::Property *ParserImpl::ParseShorthandProperty(const lexer::LexerPosition *startPos) @@ -2000,12 +1992,11 @@ bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::Property *methodStatus |= ParserStatus::GENERATOR_FUNCTION; } - lexer::TokenFlags currentTokenFlags = lexer_->GetToken().Flags(); char32_t nextCp = lexer_->Lookahead(); lexer::TokenType keywordType = lexer_->GetToken().KeywordType(); // Parse getter property if (keywordType == lexer::TokenType::KEYW_GET && !IsAccessorDelimiter(nextCp)) { - ValidateAccessor(flags, currentTokenFlags); + ValidateAccessor(flags); *propertyKind = ir::PropertyKind::GET; lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); @@ -2015,7 +2006,7 @@ bool ParserImpl::ParsePropertyModifiers(ExpressionParseFlags flags, ir::Property // Parse setter property if (keywordType == lexer::TokenType::KEYW_SET && !IsAccessorDelimiter(nextCp)) { - ValidateAccessor(flags, currentTokenFlags); + ValidateAccessor(flags); *propertyKind = ir::PropertyKind::SET; lexer_->NextToken(lexer::NextTokenFlags::KEYWORD_TO_IDENT); diff --git a/ets2panda/parser/parserImpl.cpp b/ets2panda/parser/parserImpl.cpp index 47b031611b..91c1822570 100644 --- a/ets2panda/parser/parserImpl.cpp +++ b/ets2panda/parser/parserImpl.cpp @@ -492,10 +492,6 @@ ir::ClassElement *ParserImpl::ParseClassProperty(ClassElementDescriptor *desc, ir::ClassElement *property = nullptr; if (desc->classMethod) { - if ((desc->modifiers & ir::ModifierFlags::DECLARE) != 0) { - LogError(diagnostic::DECLARE_MODIFIER_ON_INVALID_CLASS_ELEMENT); - } - property = ParseClassMethod(desc, properties, propName, &propEnd); property->SetRange({desc->propStart, propEnd}); return property; @@ -1048,10 +1044,6 @@ ir::SpreadElement *ParserImpl::ParseSpreadElement(ExpressionParseFlags flags) argument = ParseExpression(flags); } - if (inPattern && argument->IsAssignmentExpression()) { - LogError(diagnostic::RESTPARAM_INIT); - } - auto nodeType = inPattern ? ir::AstNodeType::REST_ELEMENT : ir::AstNodeType::SPREAD_ELEMENT; auto *spreadElementNode = AllocNode(nodeType, Allocator(), argument); ES2PANDA_ASSERT(spreadElementNode); diff --git a/ets2panda/parser/parserImpl.h b/ets2panda/parser/parserImpl.h index 169f3c2e7f..df362a361f 100644 --- a/ets2panda/parser/parserImpl.h +++ b/ets2panda/parser/parserImpl.h @@ -127,7 +127,7 @@ protected: ir::VariableDeclaratorFlag GetFlag(VariableParsingFlags flags); - void ValidateAccessor(ExpressionParseFlags flags, lexer::TokenFlags currentTokenFlags); + void ValidateAccessor(ExpressionParseFlags flags); void CheckPropertyKeyAsyncModifier(ParserStatus *methodStatus); ir::Property *ParseShorthandProperty(const lexer::LexerPosition *startPos); void ParseGeneratorPropertyModifier(ExpressionParseFlags flags, ParserStatus *methodStatus); diff --git a/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets b/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets new file mode 100644 index 0000000000..826c56c076 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/invalid_destructing_target.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +const f = ({a: 1}) => {} + +/* @@? 16:20 Error SyntaxError: Unexpected token '=>'. */ +/* @@? 16:20 Error SyntaxError: Invalid destructuring assignment target. */ diff --git a/ets2panda/test/ast/parser/js/static_property_prototype.js b/ets2panda/test/ast/parser/js/static_property_prototype.js new file mode 100644 index 0000000000..9162d05945 --- /dev/null +++ b/ets2panda/test/ast/parser/js/static_property_prototype.js @@ -0,0 +1,21 @@ +/* + * 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 A { + static "prototype" = 123; +} + +/* @@? 18:12 Error SyntaxError: Classes may not have static property named prototype. */ diff --git a/ets2panda/test/ast/parser/js/test_yield.js b/ets2panda/test/ast/parser/js/test_yield.js new file mode 100644 index 0000000000..172fafb5af --- /dev/null +++ b/ets2panda/test/ast/parser/js/test_yield.js @@ -0,0 +1,18 @@ +/* + * 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. + */ + +function* g(x = yield) {} + +/* @@? 16:17 Error SyntaxError: Yield is not allowed in generator parameters. */ diff --git a/ets2panda/test/ast/parser/ts/test_class_constructor.ts b/ets2panda/test/ast/parser/ts/test_class_constructor.ts new file mode 100644 index 0000000000..d525f7e842 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_class_constructor.ts @@ -0,0 +1,20 @@ +/* + * 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 MyClass { + /* @@ label */"constructor" = 42; +} + +/* @@@ label Error SyntaxError: Classes may not have a field named 'constructor'. */ diff --git a/ets2panda/test/ast/parser/ts/test_insufficient_param.ts b/ets2panda/test/ast/parser/ts/test_insufficient_param.ts new file mode 100644 index 0000000000..41ee6d2676 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_insufficient_param.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +async (()=> {}, a) /* @@ label */=> expression; + +/* @@@ label Error SyntaxError: Insufficient formal parameter in arrow function. */ diff --git a/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts b/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts new file mode 100644 index 0000000000..555dfa4bbc --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_invalid_left_side.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +({ a: 1 } = {})/* @@ label */; + +/* @@@ label Error SyntaxError: Invalid left-hand side in assignment expression. */ diff --git a/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts b/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts new file mode 100644 index 0000000000..074a68340c --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_rest_param_not_last.ts @@ -0,0 +1,17 @@ +/* + * 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. + */ +const /* @@ label */[...rest, x] = [1, 2, 3]; + +/* @@@ label Error SyntaxError: Rest parameter must be the last formal parameter. */ diff --git a/ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts b/ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts new file mode 100644 index 0000000000..327c4c4735 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_restparam_id_in_dec_context.ts @@ -0,0 +1,18 @@ +/* + * 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. + */ + +function f({ ...{ x } /* @@ label */}) {} + +/* @@@ label Error SyntaxError: RestParameter must be followed by an identifier in declaration contexts */ diff --git a/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts b/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts new file mode 100644 index 0000000000..2b09f42bf3 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_static_property_prototype.ts @@ -0,0 +1,20 @@ +/* + * 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 MyClass { + static /* @@ label */prototype = {}; +} + +/* @@@ label Error SyntaxError: Classes may not have static property named prototype. */ diff --git a/ets2panda/test/ast/parser/ts/test_unexpected_token.ts b/ets2panda/test/ast/parser/ts/test_unexpected_token.ts new file mode 100644 index 0000000000..a611c1c8f5 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_unexpected_token.ts @@ -0,0 +1,20 @@ +/* + * 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. + */ + +const obj = { + /* @@ label */+: 1 +}; + +/* @@@ label Error SyntaxError: Unexpected token. */ diff --git a/ets2panda/test/ast/parser/ts/test_yield_escaped.ts b/ets2panda/test/ast/parser/ts/test_yield_escaped.ts new file mode 100644 index 0000000000..32f77654e0 --- /dev/null +++ b/ets2panda/test/ast/parser/ts/test_yield_escaped.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + + +function* gen() { + var /* @@ label */yi\u0065ld /* @@ label1 */= 123; +} + +/* @@@ label Error SyntaxError: Escape sequences are not allowed in keyword. */ +/* @@@ label Error SyntaxError: Unexpected token. */ +/* @@@ label Error SyntaxError: Unexpected token 'yield'. */ +/* @@@ label Error SyntaxError: Unexpected identifier. */ +/* @@@ label1 Error SyntaxError: Unexpected token '='. */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 47d782ae57..c477d51103 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -33,10 +33,6 @@ syntax: id: 4 message: "Ambient class declarations must have a body." -- name: ANNOTATION_ABSTRACT - id: 29 - message: "Annotations are not allowed on an abstract class or methods." - - name: ANNOTATION_DECLARATION_ACCESS_MODIFIER id: 210 message: "Annotation declaration can not have access modifier." @@ -113,10 +109,6 @@ syntax: id: 217 message: "A binding pattern parameter cannot be optional in an implementation signature." -- name: CANNOT_EXPORT_SAME_TYPE_TWICE - id: 284 - message: "Cannot export the same '{}' type twice." - - name: CAN_NOT_FIND_NAME_TO_EXPORT id: 279 message: "Cannot find name '{}' to export." @@ -145,18 +137,10 @@ syntax: id: 127 message: "Conflicting modifiers '!' and '?' on field." -- name: CONSTANT_MULTI_INITIALIZED_IN_STATIC_BLOCK - id: 290 - message: "package constant property initialization can only be applied once in static block" - - name: DECALRE_IN_AMBIENT_CONTEXT id: 104 message: "A 'declare' modifier cannot be used in an already ambient context." -- name: DECLARE_MODIFIER_ON_INVALID_CLASS_ELEMENT - id: 157 - message: "'declare modifier cannot appear on class elements of this kind." - - name: DECORATORS_INVALID id: 183 message: "Decorators are not valid here." @@ -205,18 +189,10 @@ syntax: id: 82 message: "Duplicate group name." -- name: DUPLICATE_PROTO_FIELDS - id: 285 - message: "Duplicate __proto__ fields are not allowed in object literals" - - name: ENUM_INVALID_INIT id: 36 message: "Invalid enum initialization value" -- name: ENUM_OR_ANNOTATION_DIVIDE_BY_ZERO - id: 293 - message: "Division by zero are not allowed in Enum or Annotation" - - name: ENUM_STRING_TYPE_ALL_ITEMS_INIT id: 276 message: "All items of string-type enumeration should be explicitly initialized." @@ -692,10 +668,6 @@ syntax: id: 130 message: "Invalid right-hand side in 'instanceof' expression." -- name: INVALID_SHORTHAND_PROPERTY_INITIALIZER - id: 286 - message: "Invalid shorthand property initializer." - - name: INVALID_TYPE id: 138 message: "Invalid Type." @@ -741,10 +713,6 @@ syntax: id: 30 message: "Local class or interface declaration members can not have access modifies." -- name: LOCAL_TYPE_DEC_NO_IMPLEMENTED - id: 109 - message: "Local type declaration (class, struct, interface and enum) support is not yet implemented." - - name: META_PROP_FOR_IMPORT id: 68 message: "The only valid meta property for import is import.Meta." @@ -821,10 +789,6 @@ syntax: id: 134 message: "Namespace is allowed only at the top level or inside a namespace." -- name: NAME_CANNOT_BE_EXPORTED_AND_TYPE_EXPORTED - id: 283 - message: "Name '{}' cannot be exported and type exported at the same time." - - name: NATIVE_FLAG_ONLY_FOR_TOP_FUN id: 203 message: "'native' flags must be used for functions only at top-level." @@ -893,22 +857,6 @@ syntax: id: 193 message: "Rest parameter should be either array or tuple type." -- name: ONLY_CALL_AFTER_LAUNCH - id: 37 - message: "Only call expressions are allowed after 'launch'." - -- name: ONLY_CONSTANT_ALLOWED - id: 292 - message: "Only constant expression is expected in the field" - -- name: ONLY_CONSTANT_EXPRESSION - id: 272 - message: "Only constant expression is expected in the field" - -- name: ONLY_EXPORT_CLASS_OR_INTERFACE - id: 41 - message: "Can only type export class or interface." - - name: ONLY_SPREAD_AT_LAST_INDEX id: 143 message: "Only one spread type declaration allowed, at the last index." @@ -921,10 +869,6 @@ syntax: id: 103 message: "Only 'throws' can be used with function types." -- name: OPTIONAL_TYPES_IN_TUPLE_NOT_IMPLEMENTED - id: 142 - message: "Optional types in tuples are not yet implemented." - - name: OPTIONAL_VARIABLE id: 306 message: "Optional variable is deprecated and no longer supported." @@ -1025,18 +969,10 @@ syntax: id: 156 message: "RestParameter must be followed by an identifier in declaration contexts" -- name: RESTPARAM_INIT - id: 152 - message: "RestParameter does not support an initializer." - - name: REST_AND_DEFAULT_SAME_TIME id: 15 message: "Both optional and rest parameters are not allowed in function's parameter list." -- name: REST_PARAM_CANNOT_BE_OPTIONAL - id: 218 - message: "A rest parameter cannot be optional." - - name: REST_PARAM_LAST id: 236 message: "Rest parameter should be the last one." @@ -1085,10 +1021,6 @@ syntax: id: 136 message: "Spread type must be at the last index in the tuple type." -- name: SPREAD_TYPE_MUST_BE_ARRAY - id: 139 - message: "Spread type must be an array type." - - name: STATIC_LATE_INITIALIZATION_FIELD_INVALID_MODIFIER id: 303 message: "Late-initialized field cannot be defined as static." @@ -1101,10 +1033,6 @@ syntax: id: 198 message: "In strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement." -- name: STRING_INTERPOLATION_NOT_CONSTANT - id: 275 - message: "String Interpolation Expression is not constant expression." - - name: TAGGED_TEMPLATE_LITERALS_IN_OPTIONALCHAIN id: 56 message: "Tagged Template Literals are not allowed in optionalChain." @@ -1169,10 +1097,6 @@ syntax: id: 270 message: "Unexpected character in private identifier." -- name: UNEXPECTED_DEFAULT - id: 235 - message: "Unexpected token 'default'. Only declarations are allowed after 'export default'." - - name: UNEXPECTED_ID id: 45 message: "Unexpected identifier." @@ -1270,10 +1194,6 @@ syntax: message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal types, not annotations." -- name: UNSUPPORTED_OPERATOR_FOR_STRING - id: 274 - message: "Unsupported operator for String." - - name: UNTERMINATED_MULTI_LINE_COMMENT id: 245 message: "Unterminated multi-line comment." @@ -1323,5 +1243,25 @@ syntax: message: "Yield is not allowed in generator parameters." graveyard: +- 29 +- 37 +- 41 +- 109 +- 139 +- 142 +- 152 +- 157 +- 218 +- 235 +- 272 +- 274 +- 275 +- 283 +- 284 +- 285 +- 286 +- 290 +- 292 +- 293 - 317 # See ets_frontend/ets2panda/util/diagnostic/README.md before contributing. -- Gitee From 73dd2097620bffd93b15864d1ba272b36d5fc53f Mon Sep 17 00:00:00 2001 From: Zhelyapov Aleksey Date: Wed, 2 Jul 2025 18:07:31 +0300 Subject: [PATCH 065/107] Added warning for enum deprecated conversion Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJRYX Signed-off-by: Zhelyapov Aleksey --- ets2panda/checker/types/ets/etsEnumType.cpp | 10 +++--- ets2panda/checker/types/typeRelation.h | 1 - .../test/ast/compiler/ets/enumConversions.ets | 35 +++++++++++++++++++ .../test/ast/parser/ets/FixedArray/enum11.ets | 2 ++ ets2panda/test/ast/parser/ets/enum.ets | 2 ++ ets2panda/test/ast/parser/ets/enum11.ets | 2 ++ ets2panda/util/diagnostic/warning.yaml | 4 +++ 7 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/enumConversions.ets diff --git a/ets2panda/checker/types/ets/etsEnumType.cpp b/ets2panda/checker/types/ets/etsEnumType.cpp index 2ff91ba0ca..233a403e05 100644 --- a/ets2panda/checker/types/ets/etsEnumType.cpp +++ b/ets2panda/checker/types/ets/etsEnumType.cpp @@ -61,6 +61,7 @@ void ETSStringEnumType::Cast(TypeRelation *const relation, Type *const target) return; } if (target->IsETSStringType()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {this, target}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -70,6 +71,7 @@ void ETSStringEnumType::Cast(TypeRelation *const relation, Type *const target) void ETSStringEnumType::CastTarget(TypeRelation *relation, Type *source) { if (source->IsETSStringType()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {source, this}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -115,6 +117,7 @@ void ETSIntEnumType::Cast(TypeRelation *const relation, Type *const target) return; } if (target->HasTypeFlag(TypeFlag::ETS_NUMERIC) || target->IsBuiltinNumeric()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {this, target}, relation->GetNode()->Start()); relation->Result(true); return; } @@ -123,11 +126,8 @@ void ETSIntEnumType::Cast(TypeRelation *const relation, Type *const target) void ETSIntEnumType::CastTarget(TypeRelation *relation, Type *source) { - if (source->IsIntType()) { - relation->Result(true); - return; - } - if (source->IsBuiltinNumeric()) { + if (source->IsIntType() || source->IsBuiltinNumeric()) { + relation->RaiseError(diagnostic::ENUM_DEPRECATED_CAST, {source, this}, relation->GetNode()->Start()); relation->Result(true); return; } diff --git a/ets2panda/checker/types/typeRelation.h b/ets2panda/checker/types/typeRelation.h index ac87200fbc..33c32e789c 100644 --- a/ets2panda/checker/types/typeRelation.h +++ b/ets2panda/checker/types/typeRelation.h @@ -312,7 +312,6 @@ public: void RaiseError(const diagnostic::DiagnosticKind &kind, const lexer::SourcePosition &loc) const; void RaiseError(const diagnostic::DiagnosticKind &kind, const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const; - void LogError(const util::DiagnosticMessageParams &list, const lexer::SourcePosition &loc) const; bool Result(bool res) { diff --git a/ets2panda/test/ast/compiler/ets/enumConversions.ets b/ets2panda/test/ast/compiler/ets/enumConversions.ets new file mode 100644 index 0000000000..353ca83e8f --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/enumConversions.ets @@ -0,0 +1,35 @@ +/* + * 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 E { + a, b, c +} + +enum EE { + a, b, c, d, e +} + +function foo(e: E, i: int) { +// i = e // OK if widening, otherwise - CTE + i = e as int // CTE +// e = i // CTE + e = 1 as E // CTE +// e = E.fromValue(i) // RTE, if i is not equal to one of enum constants, otherwise OK +// e = 1 // OK, 1 can be E.b +// e = 10 // CTE, 10 is out of range +} + +/* @@? 26:7 Warning Warning: Enum cast is deprecated. Cast support from 'E' to 'Int' will be removed. */ +/* @@? 28:7 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'E' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets b/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets index e50e7e0093..44f291da40 100644 --- a/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets +++ b/ets2panda/test/ast/parser/ets/FixedArray/enum11.ets @@ -24,3 +24,5 @@ function main(): void { } /* @@@ label Error TypeError: Enum name 'Color' used in the wrong context */ +/* @@? 21:22 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ +/* @@? 22:13 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'Color' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/enum.ets b/ets2panda/test/ast/parser/ets/enum.ets index 041eb0f42f..3443eb3f6c 100644 --- a/ets2panda/test/ast/parser/ets/enum.ets +++ b/ets2panda/test/ast/parser/ets/enum.ets @@ -65,3 +65,5 @@ function main(): void { arktest.assertTrue(false) } } + +/* @@? 26:10 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ diff --git a/ets2panda/test/ast/parser/ets/enum11.ets b/ets2panda/test/ast/parser/ets/enum11.ets index 0e1d8e35b4..c78d967491 100644 --- a/ets2panda/test/ast/parser/ets/enum11.ets +++ b/ets2panda/test/ast/parser/ets/enum11.ets @@ -24,3 +24,5 @@ function main(): void { } /* @@@ label Error TypeError: Enum name 'Color' used in the wrong context */ +/* @@? 21:22 Warning Warning: Enum cast is deprecated. Cast support from 'Color' to 'Int' will be removed. */ +/* @@? 22:13 Warning Warning: Enum cast is deprecated. Cast support from 'Int' to 'Color' will be removed. */ diff --git a/ets2panda/util/diagnostic/warning.yaml b/ets2panda/util/diagnostic/warning.yaml index 71701fcf70..49f08b5c8e 100644 --- a/ets2panda/util/diagnostic/warning.yaml +++ b/ets2panda/util/diagnostic/warning.yaml @@ -29,6 +29,10 @@ warning: id: 12 message: "Detect duplicate signatures, use '{}{}' to replace" +- name: ENUM_DEPRECATED_CAST + id: 30 + message: "Enum cast is deprecated. Cast support from '{}' to '{}' will be removed." + - name: EXTENSION_MISMATCH id: 25 message: "Not matching extensions! Sourcefile: {}, Manual(used): {}" -- Gitee From 18b680db0fafb6d9e3fa9302db5e52b3dd714246 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Tue, 8 Jul 2025 20:09:32 +0800 Subject: [PATCH 066/107] Fix crash caused by invalid switch code Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKVQE Description: The modification method is to ensure that ParseTryStatement does not return nullptr in case of an exception, but instead returns AlloBrokenStatement. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/parser/ETSparserStatements.cpp | 2 +- .../test/ast/parser/ets/switch_invalid.ets | 67 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/parser/ets/switch_invalid.ets diff --git a/ets2panda/parser/ETSparserStatements.cpp b/ets2panda/parser/ETSparserStatements.cpp index 0b8fc5d913..68ffc5fa04 100644 --- a/ets2panda/parser/ETSparserStatements.cpp +++ b/ets2panda/parser/ETSparserStatements.cpp @@ -363,7 +363,7 @@ ir::Statement *ETSParser::ParseTryStatement() if (catchClauses.empty() && finalizer == nullptr) { LogError(diagnostic::MISSING_CATCH_OR_FINALLY_AFTER_TRY, {}, startLoc); - return nullptr; + return AllocBrokenStatement(startLoc); } lexer::SourcePosition endLoc = finalizer != nullptr ? finalizer->End() : catchClauses.back()->End(); diff --git a/ets2panda/test/ast/parser/ets/switch_invalid.ets b/ets2panda/test/ast/parser/ets/switch_invalid.ets new file mode 100644 index 0000000000..7c72bea595 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/switch_invalid.ets @@ -0,0 +1,67 @@ +/* + * 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. + */ + +switch:[11](q): [12]{: [13]case: [14]1:: [15]{: [16]q: [17] +=: [18]2;: +[38]try: [39]{: [40]s: [41] +=: [42]"cba";: [43]q: [44] +=: [45]5;: [46]throw: [98] + +/* @@? 16:7 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:7 Error SyntaxError: Expected '(', got ':'. */ +/* @@? 16:7 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:7 Error TypeError: Incompatible types. Found: *ERROR_TYPE*, required: char , byte , short , int, long , Char , Byte , Short , Int, Long , String or an enum type */ +/* @@? 16:15 Error SyntaxError: Expected '{', got ':'. */ +/* @@? 16:15 Error SyntaxError: Expected ')', got ':'. */ +/* @@? 16:15 Error SyntaxError: Unexpected token ':', expected 'case' or 'default'. */ +/* @@? 16:21 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:22 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:22 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:28 Error SyntaxError: Unexpected token 'case'. */ +/* @@? 16:32 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:32 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:38 Error SyntaxError: Unexpected token '1'. */ +/* @@? 16:39 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:40 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:40 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:46 Error SyntaxError: Unexpected token '{'. */ +/* @@? 16:47 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:47 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 16:53 Error SyntaxError: Unexpected token 'q'. */ +/* @@? 16:56 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 16:56 Error TypeError: Invalid left-hand side of assignment expression */ +/* @@? 16:61 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 16:63 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:69 Error SyntaxError: Unexpected token '2'. */ +/* @@? 16:71 Error SyntaxError: Unexpected token ':'. */ +/* @@? 16:71 Error TypeError: Indexed access is not supported for such expression type. */ +/* @@? 17:5 Error SyntaxError: Unexpected token 'try'. */ +/* @@? 17:5 Error SyntaxError: A try statement should contain either finally clause or at least one catch clause. */ +/* @@? 17:8 Error SyntaxError: Expected '{', got ':'. */ +/* @@? 17:8 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:14 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:15 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:21 Error SyntaxError: Unexpected token 's'. */ +/* @@? 17:24 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:29 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 17:31 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:37 Error SyntaxError: Unexpected token 'cba'. */ +/* @@? 17:43 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:49 Error SyntaxError: Unexpected token 'q'. */ +/* @@? 17:52 Error SyntaxError: Label must be followed by a loop statement. */ +/* @@? 17:57 Error SyntaxError: Invalid left-hand side in assignment expression. */ +/* @@? 17:59 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:65 Error SyntaxError: Unexpected token '5'. */ +/* @@? 17:67 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:73 Error SyntaxError: Unexpected token 'throw'. */ +/* @@? 17:78 Error SyntaxError: Unexpected token ':'. */ +/* @@? 68:1 Error SyntaxError: Expected '}', got 'end of stream'. */ -- Gitee From d9515333cf3a547da46d6f7d489ee3d22bd5aa0f Mon Sep 17 00:00:00 2001 From: oh-rgx Date: Tue, 8 Jul 2025 20:15:10 +0800 Subject: [PATCH 067/107] Fix parser crash Issue: #ICKVQZ Signed-off-by: oh-rgx --- ets2panda/parser/ETSFormattedParser.cpp | 2 +- .../test/ast/compiler/ets/parser_format.ets | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/compiler/ets/parser_format.ets diff --git a/ets2panda/parser/ETSFormattedParser.cpp b/ets2panda/parser/ETSFormattedParser.cpp index 328ed93d49..04f2616c11 100644 --- a/ets2panda/parser/ETSFormattedParser.cpp +++ b/ets2panda/parser/ETSFormattedParser.cpp @@ -161,7 +161,7 @@ ir::Statement *ETSParser::ParseStatementFormatPlaceholder() { if (insertingNodes_.empty()) { LogError(diagnostic::INSERT_NODE_ABSENT, {}, Lexer()->GetToken().Start()); - ES2PANDA_UNREACHABLE(); + return AllocBrokenStatement(Lexer()->GetToken().Start()); } ParserImpl::NodeFormatType nodeFormat = GetFormatPlaceholderType(); diff --git a/ets2panda/test/ast/compiler/ets/parser_format.ets b/ets2panda/test/ast/compiler/ets/parser_format.ets new file mode 100644 index 0000000000..a468621ea1 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/parser_format.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. + */ + +declaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaare struct MainProg2 { + @@Stave +} + +/* @@? 16:1 Error TypeError: Cannot find type 'declaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaare'. */ +/* @@? 16:1 Error TypeError: Class literal is not yet supported. */ +/* @@? 16:46 Error SyntaxError: Unexpected token 'MainProg2'. */ +/* @@? 16:46 Error TypeError: Unresolved reference MainProg2 */ +/* @@? 16:56 Error SyntaxError: Unexpected token '{'. */ +/* @@? 17:5 Error SyntaxError: There is no any node to insert at the placeholder position. */ +/* @@? 17:7 Error TypeError: Unresolved reference Stave */ -- Gitee From 807e0a3af7c7c4ae003901bee0da5275130d4eb6 Mon Sep 17 00:00:00 2001 From: sniperc96 Date: Mon, 7 Jul 2025 09:56:09 +0800 Subject: [PATCH 068/107] add new rule: RepeatNeedVirtualScroll Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKDGB Signed-off-by: sniperc96 --- ets2panda/linter/rule-config.json | 3 +- ets2panda/linter/src/lib/CookBookMsg.ts | 2 + ets2panda/linter/src/lib/FaultAttrs.ts | 1 + ets2panda/linter/src/lib/FaultDesc.ts | 1 + ets2panda/linter/src/lib/Problems.ts | 1 + ets2panda/linter/src/lib/TypeScriptLinter.ts | 52 +- .../linter/src/lib/autofixes/AutofixTitles.ts | 1 + .../linter/src/lib/autofixes/Autofixer.ts | 50 +- ets2panda/linter/src/lib/utils/TsUtils.ts | 23 + .../src/lib/utils/consts/ArkuiConstants.ts | 8 +- .../linter/test/main/repeat_virtualscroll.ets | 59 ++ .../main/repeat_virtualscroll.ets.args.json | 21 + .../main/repeat_virtualscroll.ets.arkts2.json | 288 +++++++++ .../repeat_virtualscroll.ets.autofix.json | 585 ++++++++++++++++++ .../test/main/repeat_virtualscroll.ets.json | 17 + .../main/repeat_virtualscroll.ets.migrate.ets | 74 +++ .../repeat_virtualscroll.ets.migrate.json | 17 + 17 files changed, 1181 insertions(+), 22 deletions(-) create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.json create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets create mode 100644 ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index 21370cd2c5..52426d571d 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -114,7 +114,8 @@ "arkui-no-setandprop-function", "arkui-prop-need-call-method-for-deep-copy", "arkui-no-localbuilder-decorator", - "arkui-statestyles-block-need-arrow-func" + "arkui-statestyles-block-need-arrow-func", + "arkui-repeat-disable-default-virtualscroll" ], "builtin": [ "arkts-builtin-thisArgs", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index f888fd4f5d..d94ca19217 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -371,6 +371,8 @@ cookBookTag[357] = 'Worker are not supported(arkts-no-need-stdlib-worker)'; cookBookTag[358] = 'Using "Object.getOwnPropertyNames" is not allowed in this API (arkts-builtin-object-getOwnPropertyNames))'; cookBookTag[359] = '"@LocalBuilder" Decorator is not supported (arkui-no-localbuilder-decorator)'; +cookBookTag[360] = + '"Repeat" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)'; cookBookTag[370] = 'Sparse array is not supported in ArkTS1.2 (arkts-no-sparse-array)'; cookBookTag[371] = 'Enum elements cannot be types in ArkTS1.2 (arkts-no-enum-prop-as-type)'; cookBookTag[372] = 'Smart type differences (arkts-no-ts-like-smart-type)'; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index c183485e36..faeb575025 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -256,6 +256,7 @@ faultsAttrs[FaultID.LimitedStdLibNoDoncurrentDecorator] = new FaultAttributes(35 faultsAttrs[FaultID.NoNeedStdlibWorker] = new FaultAttributes(357); faultsAttrs[FaultID.BuiltinGetOwnPropertyNames] = new FaultAttributes(358); faultsAttrs[FaultID.LocalBuilderDecoratorNotSupported] = new FaultAttributes(359); +faultsAttrs[FaultID.RepeatDisableVirtualScroll] = new FaultAttributes(360); faultsAttrs[FaultID.NosparseArray] = new FaultAttributes(370); faultsAttrs[FaultID.NoEnumPropAsType] = new FaultAttributes(371); faultsAttrs[FaultID.NoTsLikeSmartType] = new FaultAttributes(372); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index 2ae56f2bd1..33cb74aca3 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -256,3 +256,4 @@ faultDesc[FaultID.SetAndPropFunctionNotSupported] = '"setAndProp" function is no faultDesc[FaultID.PropNeedCallMethodForDeepCopy] = 'Deep copy needs to call the specific method'; faultDesc[FaultID.StateStylesBlockNeedArrowFunc] = 'StateStyles needs arrow function block'; faultDesc[FaultID.PromiseVoidNeedResolveArg] = 'Promiseconstructor only supports using resolve (undefined)'; +faultDesc[FaultID.RepeatDisableVirtualScroll] = '"Repeat" disable default "virtualScroll"'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index e8a9b611d3..9225ec1dce 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -256,6 +256,7 @@ export enum FaultID { PropNeedCallMethodForDeepCopy, StateStylesBlockNeedArrowFunc, PromiseVoidNeedResolveArg, + RepeatDisableVirtualScroll, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index ca04dbcfcd..50b2fbc071 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -92,7 +92,7 @@ import { DOUBLE_DOLLAR_IDENTIFIER, THIS_IDENTIFIER, STATE_STYLES, - CustomDecoratorName, + CustomInterfaceName, observedDecoratorName, skipImportDecoratorName, ENTRY_DECORATOR_NAME, @@ -104,7 +104,8 @@ import { PropDecoratorName, PropFunctionName, StorageTypeName, - customLayoutFunctionName + customLayoutFunctionName, + VIRTUAL_SCROLL_IDENTIFIER } from './utils/consts/ArkuiConstants'; import { arkuiImportList } from './utils/consts/ArkuiImportList'; import type { IdentifierAndArguments, ForbidenAPICheckResult } from './utils/consts/InteropAPI'; @@ -4386,7 +4387,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private handleCallExpression(node: ts.Node): void { const tsCallExpr = node as ts.CallExpression; this.checkSdkAbilityLifecycleMonitor(tsCallExpr); - this.handleStateStyles(tsCallExpr); + this.handleCallExpressionForUI(tsCallExpr); this.handleBuiltinCtorCallSignature(tsCallExpr); this.handleSdkConstructorIfaceForCallExpression(tsCallExpr); if (this.options.arkts2 && tsCallExpr.typeArguments !== undefined) { @@ -4428,6 +4429,11 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.checkRestrictedAPICall(tsCallExpr); } + private handleCallExpressionForUI(node: ts.CallExpression): void { + this.handleStateStyles(node); + this.handleCallExpressionForRepeat(node); + } + handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { if (!this.options.arkts2) { return; @@ -6904,10 +6910,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression)) { - if (node.expression.expression.text === CustomDecoratorName.Extend) { + if (node.expression.expression.text === CustomInterfaceName.Extend) { const autofix = this.autofixer?.fixExtendDecorator(node, false, this.interfacesNeedToImport); this.incrementCounters(node.parent, FaultID.ExtendDecoratorNotSupported, autofix); - } else if (node.expression.expression.text === CustomDecoratorName.AnimatableExtend) { + } else if (node.expression.expression.text === CustomInterfaceName.AnimatableExtend) { const autofix = this.autofixer?.fixExtendDecorator(node, true, this.interfacesNeedToImport); this.incrementCounters(node.parent, FaultID.AnimatableExtendDecoratorTransform, autofix); } @@ -7279,10 +7285,10 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { } private static isWrappedByExtendDecorator(node: ts.Identifier): boolean { - const wrappedSkipComponents = new Set([CustomDecoratorName.AnimatableExtend, CustomDecoratorName.Extend]); + const wrappedSkipComponents = new Set([CustomInterfaceName.AnimatableExtend, CustomInterfaceName.Extend]); if (ts.isCallExpression(node.parent)) { const expr = node.parent.expression; - if (wrappedSkipComponents.has(expr.getText()) && node.getText() !== CustomDecoratorName.AnimatableExtend) { + if (wrappedSkipComponents.has(expr.getText()) && node.getText() !== CustomInterfaceName.AnimatableExtend) { return true; } } @@ -7381,7 +7387,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } - if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomDecoratorName.Styles) { + if (!ts.isIdentifier(node.expression) || node.expression.text !== CustomInterfaceName.Styles) { return; } @@ -7565,7 +7571,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return true; }); if (filteredClassDecls.length !== 0) { - this.interfacesNeedToImport.add(CustomDecoratorName.Observed); + this.interfacesNeedToImport.add(CustomInterfaceName.Observed); } const autofix = this.autofixer?.fixDataObservation(filteredClassDecls); this.incrementCounters(node, FaultID.DataObservation, autofix); @@ -7627,7 +7633,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { private static hasObservedDecorator(classDecl: ts.ClassDeclaration): boolean { return ( ts.getDecorators(classDecl)?.some((decorator) => { - return decorator.getText() === '@' + CustomDecoratorName.Observed; + return decorator.getText() === '@' + CustomInterfaceName.Observed; }) ?? false ); } @@ -9434,7 +9440,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return; } const decoratorName = node.expression.getText(); - if (decoratorName === CustomDecoratorName.LocalBuilder) { + if (decoratorName === CustomInterfaceName.LocalBuilder) { const autofix = this.autofixer?.fixBuilderDecorators(node); this.incrementCounters(node, FaultID.LocalBuilderDecoratorNotSupported, autofix); } @@ -10014,7 +10020,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { if (decorators) { for (const decorator of decorators) { const decoratorName = TsUtils.getDecoratorName(decorator); - if (decoratorName && decoratorName === CustomDecoratorName.CustomLayout) { + if (decoratorName && decoratorName === CustomInterfaceName.CustomLayout) { return; } } @@ -11002,4 +11008,26 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { return false; } + + private handleCallExpressionForRepeat(node: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + + if ( + !ts.isIdentifier(node.expression) || + node.expression.getText() !== CustomInterfaceName.Repeat || + this.isDeclarationInSameFile(node.expression) + ) { + return; + } + + const stmt = ts.findAncestor(node, ts.isExpressionStatement); + if (!stmt || TsUtils.checkStmtHasTargetIdentifier(stmt, VIRTUAL_SCROLL_IDENTIFIER)) { + return; + } + + const autofix = this.autofixer?.fixRepeat(stmt); + this.incrementCounters(node, FaultID.RepeatDisableVirtualScroll, autofix); + } } diff --git a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts index 743f8e7382..375831c9a7 100644 --- a/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts +++ b/ets2panda/linter/src/lib/autofixes/AutofixTitles.ts @@ -65,5 +65,6 @@ export const cookBookRefToFixTitle: Map = new Map([ [341, 'Create JS objects using instantite'], [358, 'Replace missing attribute'], [359, '"@LocalBuilder" transform to "@Builder"'], + [360, '"Repeat" disable default "virtualScroll"'], [381, 'StateStyles needs arrow function block'] ]); diff --git a/ets2panda/linter/src/lib/autofixes/Autofixer.ts b/ets2panda/linter/src/lib/autofixes/Autofixer.ts index c3cab4c0e3..18d56b61ee 100644 --- a/ets2panda/linter/src/lib/autofixes/Autofixer.ts +++ b/ets2panda/linter/src/lib/autofixes/Autofixer.ts @@ -29,7 +29,7 @@ import { INSTANCE_IDENTIFIER, COMMON_METHOD_IDENTIFIER, APPLY_STYLES_IDENTIFIER, - CustomDecoratorName, + CustomInterfaceName, ARKUI_PACKAGE_NAME, VALUE_IDENTIFIER, INDENT_STEP, @@ -40,7 +40,9 @@ import { PROVIDE_DECORATOR_NAME, PROVIDE_ALIAS_PROPERTY_NAME, PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME, - NEW_PROP_DECORATOR_SUFFIX + NEW_PROP_DECORATOR_SUFFIX, + VIRTUAL_SCROLL_IDENTIFIER, + DISABLE_VIRTUAL_SCROLL_IDENTIFIER } from '../utils/consts/ArkuiConstants'; import { ES_VALUE } from '../utils/consts/ESObject'; import type { IncrementDecrementNodeInfo } from '../utils/consts/InteropAPI'; @@ -2904,7 +2906,7 @@ export class Autofixer { const newFuncDecl = Autofixer.createFunctionDeclaration(funcDecl, undefined, parameDecl, returnType, newBlock); let text = this.printer.printNode(ts.EmitHint.Unspecified, newFuncDecl, funcDecl.getSourceFile()); if (preserveDecorator) { - text = '@' + CustomDecoratorName.AnimatableExtend + this.getNewLine() + text; + text = '@' + CustomInterfaceName.AnimatableExtend + this.getNewLine() + text; } return [{ start: funcDecl.getStart(), end: funcDecl.getEnd(), replacementText: text }]; } @@ -3767,7 +3769,7 @@ export class Autofixer { const values: ts.Expression[][] = []; const statements = block?.statements; const type = ts.factory.createTypeReferenceNode( - ts.factory.createIdentifier(CustomDecoratorName.CustomStyles), + ts.factory.createIdentifier(CustomInterfaceName.CustomStyles), undefined ); Autofixer.getParamsAndValues(statements, parameters, values); @@ -3789,7 +3791,7 @@ export class Autofixer { newBlock ); const newModifiers = ts.getModifiers(methodDecl)?.filter((modifier) => { - return !(ts.isDecorator(modifier) && TsUtils.getDecoratorName(modifier) === CustomDecoratorName.Styles); + return !(ts.isDecorator(modifier) && TsUtils.getDecoratorName(modifier) === CustomInterfaceName.Styles); }); const expr = ts.factory.createPropertyDeclaration(newModifiers, methodDecl.name, undefined, type, arrowFunc); needImport.add(COMMON_METHOD_IDENTIFIER); @@ -3928,7 +3930,7 @@ export class Autofixer { fixDataObservation(classDecls: ts.ClassDeclaration[]): Autofix[] | undefined { const autofixes: Autofix[] = []; classDecls.forEach((classDecl) => { - const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.Observed)); + const observedDecorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomInterfaceName.Observed)); const sourceFile = classDecl.getSourceFile(); const text = this.printer.printNode(ts.EmitHint.Unspecified, observedDecorator, sourceFile) + this.getNewLine(); const autofix = { start: classDecl.getStart(), end: classDecl.getStart(), replacementText: text }; @@ -5069,7 +5071,7 @@ export class Autofixer { fixCustomLayout(node: ts.StructDeclaration): Autofix[] { const startPos = Autofixer.getStartPositionWithoutDecorators(node); - const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomDecoratorName.CustomLayout)); + const decorator = ts.factory.createDecorator(ts.factory.createIdentifier(CustomInterfaceName.CustomLayout)); const text = this.getNewLine() + this.printer.printNode(ts.EmitHint.Unspecified, decorator, node.getSourceFile()); return [{ start: startPos, end: startPos, replacementText: text }]; @@ -5140,4 +5142,38 @@ export class Autofixer { replacementText: newText }]; } + + fixRepeat(stmt: ts.ExpressionStatement): Autofix[] { + const newExpr = ts.factory.createCallExpression(ts.factory.createIdentifier(VIRTUAL_SCROLL_IDENTIFIER), undefined, [ + ts.factory.createObjectLiteralExpression( + [ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier(DISABLE_VIRTUAL_SCROLL_IDENTIFIER), + ts.factory.createTrue() + ) + ], + false + ) + ]); + + let identifier: ts.Identifier | undefined; + const expression = stmt.expression; + if ( + ts.isCallExpression(expression) && + ts.isPropertyAccessExpression(expression.expression) && + ts.isIdentifier(expression.expression.name) + ) { + identifier = expression.expression.name; + } + + const startPos = identifier ? identifier.getStart() : stmt.getStart(); + const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(startPos); + const indent = identifier ? lineAndCharacter.character - 1 : lineAndCharacter.character + INDENT_STEP; + const text = + this.getNewLine() + + ' '.repeat(indent) + + '.' + + this.printer.printNode(ts.EmitHint.Unspecified, newExpr, stmt.getSourceFile()); + return [{ start: stmt.getEnd(), end: stmt.getEnd(), replacementText: text }]; + } } diff --git a/ets2panda/linter/src/lib/utils/TsUtils.ts b/ets2panda/linter/src/lib/utils/TsUtils.ts index db9e766033..479705c83f 100644 --- a/ets2panda/linter/src/lib/utils/TsUtils.ts +++ b/ets2panda/linter/src/lib/utils/TsUtils.ts @@ -3804,4 +3804,27 @@ export class TsUtils { const sym = type.getSymbol(); return !!sym && sym.getName() === 'PromiseLike' && isStdLibrarySymbol(sym); } + + static checkStmtHasTargetIdentifier(stmt: ts.ExpressionStatement, target: string): boolean { + let current: ts.Node | undefined = stmt.expression; + + while (current) { + if (ts.isCallExpression(current)) { + current = current.expression; + continue; + } + + if (ts.isPropertyAccessExpression(current)) { + if (current.name.getText() === target) { + return true; + } + current = current.expression; + continue; + } + + break; + } + + return false; + } } diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts index 5405ffe91f..22e7943117 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts @@ -27,7 +27,7 @@ export const MAKE_OBSERVED = 'makeObserved'; export const ARKUI_STATE_MANAGEMENT = '@ohos.arkui.StateManagement'; export const NEW_PROP_DECORATOR_SUFFIX = 'Ref'; -export enum CustomDecoratorName { +export enum CustomInterfaceName { Extend = 'Extend', LocalBuilder = 'LocalBuilder', Styles = 'Styles', @@ -35,7 +35,8 @@ export enum CustomDecoratorName { Memo = 'Memo', Observed = 'Observed', CustomLayout = 'CustomLayout', - CustomStyles = 'CustomStyles' + CustomStyles = 'CustomStyles', + Repeat = 'Repeat' } export enum StorageTypeName { @@ -88,3 +89,6 @@ export const GET_LOCAL_STORAGE_FUNC_NAME = '__get_local_storage__'; export const PROVIDE_DECORATOR_NAME = 'Provide'; export const PROVIDE_ALIAS_PROPERTY_NAME = 'alias'; export const PROVIDE_ALLOW_OVERRIDE_PROPERTY_NAME = 'allowOverride'; + +export const VIRTUAL_SCROLL_IDENTIFIER = 'virtualScroll'; +export const DISABLE_VIRTUAL_SCROLL_IDENTIFIER = 'disableVirtualScroll'; diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets b/ets2panda/linter/test/main/repeat_virtualscroll.ets new file mode 100644 index 0000000000..62dcc3104a --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets @@ -0,0 +1,59 @@ +/* + * 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. + */ + +@Entry +@ComponentV2 +struct RepeatExampleWithTemplates { + @Local dataArr: Array = []; + + aboutToAppear(): void { + for (let i = 0; i < 50; i++) { + this.dataArr.push(`data_${i}`); + } + } + + build() { + Column() { + List() { + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30).fontColor('rgb(161,10,33)') + } + }) + + Repeat(this.dataArr) + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json new file mode 100644 index 0000000000..ee0734c0fc --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.args.json @@ -0,0 +1,21 @@ +{ + "copyright": [ + "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." + ], + "mode": { + "arkts2": "", + "autofix": "--arkts-2", + "migrate": "--arkts-2" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json new file mode 100644 index 0000000000..5a4a43a78f --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.arkts2.json @@ -0,0 +1,288 @@ +{ + "copyright": [ + "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." + ], + "result": [ + { + "line": 22, + "column": 14, + "endLine": 22, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 19, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 25, + "endLine": 22, + "endColumn": 27, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 48, + "endLine": 33, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 48, + "endLine": 43, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 48, + "endLine": 51, + "endColumn": 50, + "problem": "NumericSemantics", + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 22, + "endLine": 41, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 22, + "endLine": 49, + "endColumn": 32, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 21, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 19, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json new file mode 100644 index 0000000000..e7463248c2 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.autofix.json @@ -0,0 +1,585 @@ +{ + "copyright": [ + "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." + ], + "result": [ + { + "line": 22, + "column": 14, + "endLine": 22, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 739, + "end": 744, + "replacementText": "i: number = 0", + "line": 22, + "column": 14, + "endLine": 22, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 19, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 743, + "end": 744, + "replacementText": "0.0", + "line": 22, + "column": 18, + "endLine": 22, + "endColumn": 19 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 22, + "column": 25, + "endLine": 22, + "endColumn": 27, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 750, + "end": 752, + "replacementText": "50.0", + "line": 22, + "column": 25, + "endLine": 22, + "endColumn": 27 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 48, + "endLine": 33, + "endColumn": 50, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1007, + "end": 1009, + "replacementText": "30.0", + "line": 33, + "column": 48, + "endLine": 33, + "endColumn": 50 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1494, + "end": 1494, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 48, + "endLine": 43, + "endColumn": 50, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1358, + "end": 1360, + "replacementText": "30.0", + "line": 43, + "column": 48, + "endLine": 43, + "endColumn": 50 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1717, + "end": 1717, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 48, + "endLine": 51, + "endColumn": 50, + "problem": "NumericSemantics", + "autofix": [ + { + "start": 1659, + "end": 1661, + "replacementText": "30.0", + "line": 51, + "column": 48, + "endLine": 51, + "endColumn": 50 + } + ], + "suggest": "", + "rule": "Numeric semantics is different for integer values (arkts-numeric-semantic)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37, + "problem": "RepeatDisableVirtualScroll", + "autofix": [ + { + "start": 1755, + "end": 1755, + "replacementText": "\n .virtualScroll({ disableVirtualScroll: true })", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 37 + } + ], + "suggest": "", + "rule": "\"Repeat\" natively supports virtual scrolling capability in ArkTS1.2, so the default virtual scrolling should be disabled (arkui-repeat-disable-default-virtualscroll)", + "severity": "ERROR" + }, + { + "line": 16, + "column": 2, + "endLine": 16, + "endColumn": 7, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 17, + "column": 2, + "endLine": 17, + "endColumn": 13, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 19, + "column": 4, + "endLine": 19, + "endColumn": 9, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 28, + "column": 5, + "endLine": 28, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Column\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 29, + "column": 7, + "endLine": 29, + "endColumn": 11, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"List\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 9, + "endLine": 30, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 31, + "column": 22, + "endLine": 31, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 32, + "column": 13, + "endLine": 32, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 15, + "endLine": 33, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 9, + "endLine": 40, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 22, + "endLine": 41, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 42, + "column": 13, + "endLine": 42, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 15, + "endLine": 43, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 9, + "endLine": 48, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 22, + "endLine": 49, + "endColumn": 32, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"RepeatItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 13, + "endLine": 50, + "endColumn": 21, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"ListItem\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 51, + "column": 15, + "endLine": 51, + "endColumn": 19, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Text\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15, + "problem": "UIInterfaceImport", + "autofix": [ + { + "start": 603, + "end": 603, + "replacementText": "\n\nimport {\n Entry,\n ComponentV2,\n Local,\n Column,\n List,\n Repeat,\n RepeatItem,\n ListItem,\n Text,\n} from '@kit.ArkUI';", + "line": 55, + "column": 9, + "endLine": 55, + "endColumn": 15 + } + ], + "suggest": "", + "rule": "The ArkUI interface \"Repeat\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets new file mode 100644 index 0000000000..07d143184d --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.ets @@ -0,0 +1,74 @@ +/* + * 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. + */ + +import { + Entry, + ComponentV2, + Local, + Column, + List, + Repeat, + RepeatItem, + ListItem, + Text, +} from '@kit.ArkUI'; + +@Entry +@ComponentV2 +struct RepeatExampleWithTemplates { + @Local dataArr: Array = []; + + aboutToAppear(): void { + for (let i: number = 0.0; i < 50.0; i++) { + this.dataArr.push(`data_${i}`); + } + } + + build() { + Column() { + List() { + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30.0).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30.0).fontColor('rgb(161,10,33)') + } + }) + .key((item: string, index: number): string => JSON.stringify(item)) + .virtualScroll({ disableVirtualScroll: true }) + + Repeat(this.dataArr) + .each((ri: RepeatItem) => { + ListItem() { + Text('each_' + ri.item).fontSize(30.0).fontColor('rgb(161,10,33)') + } + }) + .virtualScroll({ disableVirtualScroll: true }) + + Repeat(this.dataArr) + .virtualScroll({ disableVirtualScroll: true }) + } + } + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json new file mode 100644 index 0000000000..ca88f857e9 --- /dev/null +++ b/ets2panda/linter/test/main/repeat_virtualscroll.ets.migrate.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "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." + ], + "result": [] +} \ No newline at end of file -- Gitee From 52fb11ed39785fd90abca71263d1ddee922fe6f3 Mon Sep 17 00:00:00 2001 From: Tamas Toth Date: Thu, 22 May 2025 13:19:52 +0200 Subject: [PATCH 069/107] Fix re-exporting from the same file causes crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/IC9UW9 Fixes #25365 internal issue Signed-off-by: Tamas Toth Change-Id: Ibb676432bea6d89eba217e5fcdbb33ae5c786495 --- ets2panda/parser/ETSparser.cpp | 19 +++++++++++++++---- ets2panda/parser/ETSparser.h | 3 +++ .../ets/re_export/re_export_circular.ets | 18 ++++++++++++++++++ ets2panda/util/diagnostic/syntax.yaml | 4 ++++ 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9e2059c27d..2462dc5835 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -1103,6 +1103,20 @@ void ETSParser::ReportIfVarDeclaration(VariableParsingFlags flags) } } +ir::Statement *ETSParser::CreateReExportDeclarationNode(ir::ETSImportDeclaration *reExportDeclaration, + const lexer::SourcePosition &startLoc, + const ir::ModifierFlags &modifiers) +{ + if (GetProgram()->AbsoluteName().Is(reExportDeclaration->ResolvedSource())) { + LogError(diagnostic::RE_EXPORTING_LOCAL_BINDINGS_IS_NOT_ALLOWED, {}, startLoc); + return AllocBrokenStatement(startLoc); + } + auto reExport = AllocNode(reExportDeclaration, std::vector(), + GetProgram()->AbsoluteName(), Allocator()); + reExport->AddModifier(modifiers); + return reExport; +} + ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::ModifierFlags modifiers) { const size_t exportDefaultMaxSize = 1; @@ -1154,10 +1168,7 @@ ir::Statement *ETSParser::ParseExport(lexer::SourcePosition startLoc, ir::Modifi } // re-export directive auto *reExportDeclaration = ParseImportPathBuildImport(std::move(specifiers), true, startLoc, ir::ImportKinds::ALL); - auto reExport = AllocNode(reExportDeclaration, std::vector(), - GetProgram()->AbsoluteName(), Allocator()); - reExport->AddModifier(modifiers); - return reExport; + return CreateReExportDeclarationNode(reExportDeclaration, startLoc, modifiers); } ir::ETSPackageDeclaration *ETSParser::ParsePackageDeclaration() diff --git a/ets2panda/parser/ETSparser.h b/ets2panda/parser/ETSparser.h index b9be64d56c..a2b40abbd9 100644 --- a/ets2panda/parser/ETSparser.h +++ b/ets2panda/parser/ETSparser.h @@ -188,6 +188,9 @@ private: #endif ir::ETSImportDeclaration *ParseImportPathBuildImport(ArenaVector &&specifiers, bool requireFrom, lexer::SourcePosition startLoc, ir::ImportKinds importKind); + ir::Statement *CreateReExportDeclarationNode(ir::ETSImportDeclaration *reExportDeclaration, + const lexer::SourcePosition &startLoc, + const ir::ModifierFlags &modifiers); void ParseNamedExportSpecifiers(ArenaVector *specifiers, bool defaultExport); void ParseUserSources(std::vector userParths); ArenaVector ParseTopLevelDeclaration(); diff --git a/ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets b/ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets new file mode 100644 index 0000000000..bfc5c191e6 --- /dev/null +++ b/ets2panda/test/ast/parser/ets/re_export/re_export_circular.ets @@ -0,0 +1,18 @@ +/* + * 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. + */ + +export {foo} from "./re_export_circular.ets" + +/* @@? 16:8 Error SyntaxError: Re-exporting local bindings is not allowed */ diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 47d782ae57..fbff3a25f1 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -1053,6 +1053,10 @@ syntax: id: 287 message: "Unexpected return value." +- name: RE_EXPORTING_LOCAL_BINDINGS_IS_NOT_ALLOWED + id: 138237 + message: "Re-exporting local bindings is not allowed" + - name: SETTER_FORMAL_PARAMS id: 63 message: "Setter must have exactly one formal parameter." -- Gitee From c6ac3f679d584d5232c5baacdeafc4215f5ba9c2 Mon Sep 17 00:00:00 2001 From: zmw Date: Tue, 8 Jul 2025 23:06:10 +0800 Subject: [PATCH 070/107] Fix switchCase clone crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKWR1 Description: Fix switchCase clone crash Signed-off-by: zmw --- ets2panda/parser/statementParser.cpp | 1 + ...lid_switch_case_in_function_assignment.ets | 25 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets diff --git a/ets2panda/parser/statementParser.cpp b/ets2panda/parser/statementParser.cpp index 756ce32cc8..e0d55a765c 100644 --- a/ets2panda/parser/statementParser.cpp +++ b/ets2panda/parser/statementParser.cpp @@ -1209,6 +1209,7 @@ ir::SwitchCaseStatement *ParserImpl::ParseSwitchCaseStatement(bool *seenDefault) default: { LogError(diagnostic::UNEXPECTED_TOKEN_PARAM_EXPECTED_CASE_OR_DEFAULT, {lexer::TokenToString(lexer_->GetToken().Type())}); + testExpr = AllocBrokenExpression(caseStartLoc); } } diff --git a/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets b/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets new file mode 100644 index 0000000000..37691e5067 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/invalid_switch_case_in_function_assignment.ets @@ -0,0 +1,25 @@ +/* + * 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. + */ + +let a = foo() { + switch (x) { + "unreachable" + } +} + +/* @@? 16:9 Error TypeError: Unresolved reference foo */ +/* @@? 16:9 Error TypeError: This expression is not callable. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'string literal', expected 'case' or 'default'. */ +/* @@? 18:9 Error SyntaxError: Expected ':', got 'string literal'. */ -- Gitee From 9403aaec64a9d400e73eba9638e320cf07dc692f Mon Sep 17 00:00:00 2001 From: dongchao Date: Sun, 6 Jul 2025 14:41:30 +0800 Subject: [PATCH 071/107] Change the enum in glue code in declgen_ets2ts Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICK9ZG Signed-off-by: dongchao Change-Id: I45d9d1957a037943d8eace6f84e83229b48e55ae --- ets2panda/declgen_ets2ts/declgenEts2Ts.cpp | 23 +++++++--------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index 132354d874..b37db2b236 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -489,22 +489,18 @@ void TSDeclGen::GenLiteral(const ir::Literal *literal) const auto number = literal->AsNumberLiteral()->Number(); if (number.IsInt()) { OutDts(std::to_string(number.GetInt())); - OutTs(std::to_string(number.GetInt())); return; } if (number.IsLong()) { OutDts(std::to_string(number.GetLong())); - OutTs(std::to_string(number.GetLong())); return; } if (number.IsFloat()) { OutDts(std::to_string(number.GetFloat())); - OutTs(std::to_string(number.GetFloat())); return; } if (number.IsDouble()) { OutDts(std::to_string(number.GetDouble())); - OutTs(std::to_string(number.GetDouble())); return; } LogError(diagnostic::UNEXPECTED_NUMBER_LITERAL_TYPE, {}, literal->Start()); @@ -512,7 +508,6 @@ void TSDeclGen::GenLiteral(const ir::Literal *literal) const auto string = literal->AsStringLiteral()->ToString(); importSet_.insert(string); OutDts("\"" + string + "\""); - OutTs("\"" + string + "\""); } else if (literal->IsBooleanLiteral()) { OutDts(literal->AsBooleanLiteral()->ToString()); } else { @@ -1547,12 +1542,10 @@ void TSDeclGen::GenEnumDeclaration(const ir::ClassProperty *enumMember) ProcessIndent(); OutDts(GetKeyIdent(enumMember->Key())->Name()); - OutTs(GetKeyIdent(enumMember->Key())->Name()); const auto *init = originEnumMember->Init(); if (init != nullptr) { OutDts(" = "); - OutTs(" = "); if (!init->IsLiteral()) { LogError(diagnostic::NOT_LITERAL_ENUM_INITIALIZER, {}, init->Start()); } @@ -1560,8 +1553,6 @@ void TSDeclGen::GenEnumDeclaration(const ir::ClassProperty *enumMember) GenLiteral(init->AsLiteral()); } - OutTs(","); - OutEndlTs(); OutDts(","); OutEndlDts(); } @@ -1739,8 +1730,6 @@ void TSDeclGen::EmitClassDeclaration(const ir::ClassDefinition *classDef, const OutEndlTs(); } else if (classDef->IsEnumTransformed()) { EmitDeclarationPrefix(classDef, "enum ", className); - OutTs("export const enum ", className, " {"); - OutEndlTs(); } else if (classDef->IsFromStruct()) { EmitDeclarationPrefix(classDef, "struct ", className); } else if (classDef->IsAbstract()) { @@ -1776,9 +1765,9 @@ void TSDeclGen::GenPartName(std::string &partName) void TSDeclGen::ProcessIndent() { - if (state_.isInterfaceInNamespace) { + if (state_.isInterfaceInNamespace || state_.inEnum) { OutDts(GetIndent()); - } else if (classNode_.hasNestedClass || state_.inNamespace || state_.inEnum) { + } else if (classNode_.hasNestedClass || state_.inNamespace) { auto indent = GetIndent(); OutDts(indent); OutTs(indent); @@ -1938,7 +1927,7 @@ void TSDeclGen::GenClassDeclaration(const ir::ClassDeclaration *classDecl) } if (!state_.inGlobalClass && ShouldEmitDeclarationSymbol(classDef->Ident())) { HandleClassDeclarationTypeInfo(classDef, className); - if (!classDef->IsNamespaceTransformed() && !classDef->IsEnumTransformed()) { + if (!classDef->IsNamespaceTransformed()) { EmitClassGlueCode(classDef, className); } ProcessClassBody(classDef); @@ -1953,10 +1942,12 @@ void TSDeclGen::GenClassDeclaration(const ir::ClassDeclaration *classDecl) return; } ES2PANDA_ASSERT(classNode_.indentLevel != static_cast(-1)); - if (!state_.isClassInNamespace || state_.inEnum) { - state_.inEnum = false; + if (!state_.isClassInNamespace) { CloseClassBlock(false); } + if (state_.inEnum) { + state_.inEnum = false; + } } if (classDef->IsDefaultExported()) { OutDts("export default ", className, ";"); -- Gitee From eb69090fb1d5fff132656680e04ca5d715638ab3 Mon Sep 17 00:00:00 2001 From: fcc Date: Tue, 8 Jul 2025 17:49:46 +0800 Subject: [PATCH 072/107] fix crash when function type is TypeError Ensure type IsETSFunctionType before AsETSFunctionType. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKU8S Signed-off-by: fcc t commit --amend --- ets2panda/checker/ets/function.cpp | 2 +- ets2panda/checker/ets/helpers.cpp | 3 +- ets2panda/checker/ets/object.cpp | 2 +- .../ast/compiler/ets/function_typeerror.ets | 55 +++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/function_typeerror.ets diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index a9a099ad1c..15581ce444 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1927,7 +1927,7 @@ bool ETSChecker::CheckOverride(Signature *signature, ETSObjectType *site) auto *target = site->GetProperty(signature->Function()->Id()->Name(), flags); bool isOverridingAnySignature = false; - if (target == nullptr) { + if (target == nullptr || target->TsType() == nullptr || !target->TsType()->IsETSFunctionType()) { return isOverridingAnySignature; } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index f04187a77f..d2660c20b0 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -65,7 +65,8 @@ bool ETSChecker::IsVariableStatic(const varbinder::Variable *var) { CHECK_NOT_NULL(var); if (var->HasFlag(varbinder::VariableFlags::METHOD)) { - return var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); + return var->TsType()->IsETSFunctionType() && + var->TsType()->AsETSFunctionType()->CallSignatures()[0]->HasSignatureFlag(SignatureFlags::STATIC); } return var->HasFlag(varbinder::VariableFlags::STATIC); } diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index c72441cdc6..f3d2c27be6 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -112,7 +112,7 @@ static bool CheckFunctionDecl(varbinder::LocalVariable *child, varbinder::LocalV return false; } ES2PANDA_ASSERT(child->Declaration()->Type() == parent->Declaration()->Type()); - if (!child->TsType()->IsETSMethodType()) { + if (!child->TsType()->IsETSMethodType() || !parent->TsType()->IsETSMethodType()) { return true; } diff --git a/ets2panda/test/ast/compiler/ets/function_typeerror.ets b/ets2panda/test/ast/compiler/ets/function_typeerror.ets new file mode 100644 index 0000000000..969d9217be --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/function_typeerror.ets @@ -0,0 +1,55 @@ +/* + * 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 { + methodOne(this.ownerType!, this.name): Base { + return p; + } +} + +class Derived extends Base { + override methodOne(p: Derived): Base { + return p; + } +} + +function main(): void { + let a = new Base(); + let b = new Derived() + + let resultA = a.methodOne(a); + let resultB = b.methodOne(b); + + arktest.assertEQ(resultA, resultB); +} + +/* @@? 17:14 Error TypeError: Only abstract or native methods can't have body. */ +/* @@? 17:19 Error SyntaxError: Unexpected token, expected ',' or ')'. */ +/* @@? 17:19 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:19 Error SyntaxError: The function parameter 'this' must explicitly specify the typeAnnotation. */ +/* @@? 17:30 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:30 Error SyntaxError: Unexpected token ','. */ +/* @@? 17:32 Error SyntaxError: Unexpected token 'this'. */ +/* @@? 17:36 Error SyntaxError: Unexpected token '.'. */ +/* @@? 17:41 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:41 Error SyntaxError: Unexpected token ')'. */ +/* @@? 17:42 Error SyntaxError: Unexpected token ':'. */ +/* @@? 17:48 Error SyntaxError: Field type annotation expected. */ +/* @@? 17:49 Error SyntaxError: Unexpected token '{'. */ +/* @@? 18:9 Error SyntaxError: Unexpected token 'return'. */ +/* @@? 18:17 Error SyntaxError: Field type annotation expected. */ +/* @@? 20:1 Error SyntaxError: Unexpected token '}'. */ +/* @@? 23:23 Error TypeError: Method methodOne(p: Derived): Base in Derived not overriding any method */ +/* @@? 32:21 Error TypeError: Property 'methodOne' does not exist on type 'Base' */ -- Gitee From 421db810e8152925537b7121701d865a30c6754f Mon Sep 17 00:00:00 2001 From: oh-rgx Date: Wed, 9 Jul 2025 15:59:23 +0800 Subject: [PATCH 073/107] Fix createPartial crash Issue: #ICL3JG Signed-off-by: oh-rgx --- ets2panda/parser/ETSparserClasses.cpp | 3 +- .../ast/compiler/ets/interface_partial.ets | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/ast/compiler/ets/interface_partial.ets diff --git a/ets2panda/parser/ETSparserClasses.cpp b/ets2panda/parser/ETSparserClasses.cpp index 8807006489..62bc6c1933 100644 --- a/ets2panda/parser/ETSparserClasses.cpp +++ b/ets2panda/parser/ETSparserClasses.cpp @@ -1021,7 +1021,8 @@ ir::ModifierFlags ETSParser::ParseInterfaceMethodModifiers() ir::TypeNode *ETSParser::ParseInterfaceTypeAnnotation(ir::Identifier *name) { if (!Lexer()->TryEatTokenType(lexer::TokenType::PUNCTUATOR_COLON) && - Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT) { + Lexer()->GetToken().Type() != lexer::TokenType::LITERAL_IDENT && + Lexer()->GetToken().Type() != lexer::TokenType::PUNCTUATOR_RIGHT_BRACE) { LogError(diagnostic::INTERFACE_FIELDS_TYPE_ANNOTATION); Lexer()->GetToken().SetTokenType(lexer::TokenType::PUNCTUATOR_COLON); Lexer()->NextToken(); diff --git a/ets2panda/test/ast/compiler/ets/interface_partial.ets b/ets2panda/test/ast/compiler/ets/interface_partial.ets new file mode 100644 index 0000000000..f3f836c47b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/interface_partial.ets @@ -0,0 +1,40 @@ +/* + * 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. + */ + +interface I { + arr +} + +function foo (bar: Partial) { + if (bar.var_one != undefined) { + bar.var_one = "asddsf"; + } +} + +function main() { + let a : I = {var_one: "initial_var_one", var_two: "initial_var_two_a"}; + foo(a.var_one); + let a : I = {var_two: "initial_var_two_b"}; + foo(break.var_one); +} + +/* @@? 18:1 Error SyntaxError: Invalid Type. */ +/* @@? 21:13 Error TypeError: Property 'var_one' does not exist on type 'I$partial' */ +/* @@? 22:13 Error TypeError: Property 'var_one' does not exist on type 'I$partial' */ +/* @@? 27:18 Error TypeError: type I has no property named var_one */ +/* @@? 28:11 Error TypeError: Property 'var_one' does not exist on type 'I' */ +/* @@? 29:9 Error TypeError: Variable 'a' has already been declared. */ +/* @@? 29:18 Error TypeError: type I has no property named var_two */ +/* @@? 30:9 Error SyntaxError: Unexpected token 'break'. */ \ No newline at end of file -- Gitee From 2f688626e6c0280166c469a99b19abe236d36076 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Wed, 9 Jul 2025 16:33:04 +0800 Subject: [PATCH 074/107] Fixing invalid call function crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICL4JI Description: Problem Description: Circular dependency element, tstype without expr set to TypeError, subsequent use of nullptr's tstype causes segv Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/checker/ETSAnalyzer.cpp | 1 + .../compiler/ets/fuzz_invalid_property.ets | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 1fec1bafe8..4baf7a0571 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1672,6 +1672,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const checker::TypeStackElement tse(checker, expr, {{diagnostic::CYCLIC_CALLEE, {}}}, expr->Start()); if (tse.HasTypeError()) { + expr->SetTsType(checker->GlobalTypeError()); return checker->GlobalTypeError(); } diff --git a/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets b/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets new file mode 100644 index 0000000000..39746c2c66 --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/fuzz_invalid_property.ets @@ -0,0 +1,29 @@ +/* + * 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 D{ + strB = (new StringBuilder).append('{ ').append(strB.toString()).append(' }') +} + +/* @@? 17:12 Error TypeError: Circular call function */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Boolean): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Byte): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Short): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Char): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Int): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Long): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Float): StringBuilder` */ +/* @@? 17:12 Error TypeError: Call to `append` is ambiguous as `2` versions of `append` are available: `append(s: String): StringBuilder` and `append(i: Double): StringBuilder` */ +/* @@? 17:52 Error TypeError: Property 'strB' must be accessed through 'this' */ -- Gitee From b74c8e5fef2624f624b038f1aa135f389b29419b Mon Sep 17 00:00:00 2001 From: fcc Date: Wed, 9 Jul 2025 10:04:25 +0800 Subject: [PATCH 075/107] fix index out of bounds when fold template string Ensure the index is in the bounds of vector. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKYF7 Signed-off-by: fcc --- .../ets/constantExpressionLowering.cpp | 15 ++++++--------- .../test/ast/compiler/ets/template_fold.ets | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/template_fold.ets diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 7307d9f8c9..6a08c07932 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1127,17 +1127,14 @@ static ir::AstNode *FoldTemplateLiteral(ir::TemplateLiteral *expr, ArenaAllocato auto quasis = expr->Quasis(); auto expressions = expr->Expressions(); - if (!quasis.empty() && !quasis[0]->Raw().Empty()) { - result.Append(quasis[0]->Cooked()); - } - - auto const num = expressions.size(); - std::size_t i = 0U; - while (i < num) { - result.Append(litToString(expressions[i]->AsLiteral())); - if (!quasis[++i]->Raw().Empty()) { + auto const num = std::max(expressions.size(), quasis.size()); + for (std::size_t i = 0U; i < num; i++) { + if (i < quasis.size()) { result.Append(quasis[i]->Cooked()); } + if (i < expressions.size()) { + result.Append(litToString(expressions[i]->AsLiteral())); + } } auto *strLit = util::NodeAllocator::Alloc(allocator, result.View()); diff --git a/ets2panda/test/ast/compiler/ets/template_fold.ets b/ets2panda/test/ast/compiler/ets/template_fold.ets new file mode 100644 index 0000000000..c4255f98ba --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/template_fold.ets @@ -0,0 +1,19 @@ +/* + * 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. + */ + +`\0#{(new (Reflect)() ? new () : {f: [], : 2})}${true}` + +/* @@? 16:2 Error SyntaxError: Octal escape sequences are not allowed in template strings. */ + -- Gitee From 6363d358a441f86c08e0fc2d469f50d6256ae67d Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Tue, 8 Jul 2025 11:43:14 +0800 Subject: [PATCH 076/107] Fix anotation bug Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKPHG?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/parser/TypedParser.cpp | 1 - .../annotation_for_type_parameter02.ets | 29 +++++++------------ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index cc626c2ed9..6cb2b38aae 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -1303,7 +1303,6 @@ ir::AstNode *TypedParser::ParseTypeParameterInstantiationImpl(TypeAnnotationPars TypeAnnotationParsingOptions tmpOptions = *options &= ~TypeAnnotationParsingOptions::IGNORE_FUNCTION_TYPE; // Need to parse correctly the cases like `x: T|C` tmpOptions &= ~TypeAnnotationParsingOptions::DISALLOW_UNION; - tmpOptions |= TypeAnnotationParsingOptions::ANNOTATION_NOT_ALLOW; ir::TypeNode *currentParam = ParseTypeAnnotation(&tmpOptions); if (currentParam == nullptr) { diff --git a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets index e4e023e3bb..86cf1c3590 100644 --- a/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets +++ b/ets2panda/test/ast/compiler/ets/annotation_tests/annotation_for_type_parameter02.ets @@ -12,26 +12,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -@interface Anno{} +@Retention("SOURCE") +@interface Anno{ } -let array1: Array<@Anno() Int> = new Array<@Anno() Int>() +let array1: Array<@Anno() Int > = new Array < @Anno() Int > () -class A{ - foo(){} - bar(){ - foo<@Anno T>() - this.foo<@Anno T>() - } +class A { + foo() { } + bar() { + foo < @Anno number > () + this.foo < @Anno number > () + } } -function foo(){} -foo<@Anno T>() +function foo() { } +foo < @Anno string > () -/* @@? 17:27 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 17:52 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 22:17 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 22:17 Error TypeError: Cannot find type 'T'. */ -/* @@? 23:22 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 23:22 Error TypeError: Cannot find type 'T'. */ -/* @@? 28:11 Error SyntaxError: Annotations are not allowed on this type of declaration. */ -/* @@? 28:11 Error TypeError: Cannot find type 'T'. */ -- Gitee From 20bb0ec14b76ddeeaa88ea7db7f3e0ef2001c3f9 Mon Sep 17 00:00:00 2001 From: fcc Date: Tue, 8 Jul 2025 16:27:35 +0800 Subject: [PATCH 077/107] Fix lambda with rest param and optional params Compiler crash when lambda have both rest param and optional params. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKSX8 Signed-off-by: fcc --- ets2panda/checker/types/ets/etsFunctionType.cpp | 3 ++- ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ets2panda/checker/types/ets/etsFunctionType.cpp b/ets2panda/checker/types/ets/etsFunctionType.cpp index ae07ae9762..58c4ea3cea 100644 --- a/ets2panda/checker/types/ets/etsFunctionType.cpp +++ b/ets2panda/checker/types/ets/etsFunctionType.cpp @@ -76,7 +76,8 @@ static ETSObjectType *FunctionTypeToFunctionalInterfaceType(ETSChecker *checker, bool isExtensionHack = signature->HasSignatureFlag(SignatureFlags::EXTENSION_FUNCTION); if (signature->RestVar() != nullptr) { - auto nPosParams = signature->Params().size(); + auto sigParamsSize = signature->Params().size(); + auto nPosParams = arity < sigParamsSize ? arity : sigParamsSize; auto *functionN = checker->GlobalBuiltinFunctionType(nPosParams, true); auto substitution = Substitution {}; for (size_t i = 0; i < nPosParams; i++) { diff --git a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt index 008c22e9c0..af11a06df6 100644 --- a/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt +++ b/ets2panda/test/test-lists/ets-runtime/ets-runtime-ignored.txt @@ -109,9 +109,7 @@ inferTypeLambda_14.ets enum_const_variable.ets enumConstExpression.ets local_enum03.ets -lambda_with_restparameter_optinal.ets overload-primitive-and-object.ets -lambda_with_restparameter_optinal_fixedarray.ets finallyTryAbruptedByReturn.ets Recursive_Parameter_2.ets Recursive_Parameter_3.ets -- Gitee From dd2cb694c8dd5541084d6f4fbed4ad466f412d58 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Thu, 10 Jul 2025 11:38:08 +0800 Subject: [PATCH 078/107] Fix the circular dependency crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICLCV5?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ETSAnalyzer.cpp | 1 + .../ets/circular_dependency_crash.ets | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 1fec1bafe8..4baf7a0571 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -1672,6 +1672,7 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const checker::TypeStackElement tse(checker, expr, {{diagnostic::CYCLIC_CALLEE, {}}}, expr->Start()); if (tse.HasTypeError()) { + expr->SetTsType(checker->GlobalTypeError()); return checker->GlobalTypeError(); } diff --git a/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets b/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets new file mode 100644 index 0000000000..5315c5449b --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/circular_dependency_crash.ets @@ -0,0 +1,21 @@ +/* + * 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. + */ + +function foo() { + let s = "2".concat(s).concat("4"); +} + +/* @@? 17:13 Error TypeError: Circular call function */ +/* @@? 17:24 Error TypeError: Variable 's' is accessed before it's initialization. */ \ No newline at end of file -- Gitee From 49c4d63edfb43ba044d2912bb888f7b540129892 Mon Sep 17 00:00:00 2001 From: xuxinjie4 Date: Sat, 5 Jul 2025 16:02:21 +0800 Subject: [PATCH 079/107] Fix interop bug patch2 Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICKZ5H?from=project-issue Signed-off-by: xuxinjie4 --- ets2panda/checker/ETSAnalyzer.cpp | 4 +- ets2panda/checker/ETSchecker.h | 1 + ets2panda/checker/ets/object.cpp | 17 +- ets2panda/checker/ets/typeCheckingHelpers.cpp | 3 +- ets2panda/checker/ets/utilityTypeHandlers.cpp | 2 +- ets2panda/checker/types/ets/etsAnyType.cpp | 2 +- ets2panda/checker/types/gradualType.cpp | 39 +- ets2panda/compiler/core/ETSCompiler.cpp | 3 +- .../compiler/lowering/ets/enumLowering.cpp | 2 +- .../lowering/ets/gradualTypeNarrowing.cpp | 4 + .../ets/interfaceObjectLiteralLowering.cpp | 4 +- .../lowering/ets/objectIndexAccess.cpp | 6 +- .../lowering/ets/objectLiteralLowering.cpp | 31 +- .../ets/topLevelStmts/globalClassHandler.cpp | 6 +- ets2panda/compiler/lowering/phase.cpp | 2 +- ets2panda/evaluate/scopedDebugInfoPlugin.cpp | 3 +- ets2panda/ir/ets/etsModule.cpp | 2 +- ets2panda/ir/ets/etsModule.h | 13 +- ets2panda/ir/ts/tsEnumDeclaration.cpp | 2 +- ets2panda/ir/ts/tsEnumDeclaration.h | 23 +- ets2panda/ir/ts/tsInterfaceDeclaration.h | 2 +- ets2panda/parser/ETSparser.cpp | 14 +- ets2panda/parser/ETSparserEnums.cpp | 6 +- ets2panda/parser/ETSparserNamespaces.cpp | 8 +- ets2panda/parser/TypedParser.cpp | 5 +- .../dynamic_type_import.ets | 28 ++ .../dynamic_decl_import.ets | 2 +- .../modules/module-expected.txt | 397 +++++++++++++++++- .../dynamic_import_tests/modules/module.ets | 8 +- .../plugin_conversion_rule_part_iii.cpp | 5 +- .../plugin_conversion_rule_part_iv.cpp | 16 +- .../ast-builders/tsEnumDeclarationBuilder.h | 5 +- 32 files changed, 583 insertions(+), 82 deletions(-) create mode 100644 ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 1fec1bafe8..0a1d71a7c1 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2022,7 +2022,7 @@ checker::Type *ETSAnalyzer::CheckDynamic(ir::ObjectExpression *expr) const static bool ValidatePreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { - auto preferredType = expr->PreferredType(); + auto preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); if (preferredType == nullptr) { checker->LogError(diagnostic::CLASS_COMPOSITE_UNKNOWN_TYPE, {}, expr->Start()); return false; @@ -2381,7 +2381,7 @@ checker::ETSObjectType *ResolveUnionObjectTypeForObjectLiteral(ETSChecker *check static checker::ETSObjectType *ResolveObjectTypeFromPreferredType(ETSChecker *checker, ir::ObjectExpression *expr) { // Assume not null, checked by caller in Check() - checker::Type *preferredType = expr->PreferredType(); + checker::Type *preferredType = expr->PreferredType()->MaybeBaseTypeOfGradualType(); if (preferredType->IsETSAsyncFuncReturnType()) { preferredType = preferredType->AsETSAsyncFuncReturnType()->GetPromiseTypeArg(); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 2a61082efb..61b330ae70 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -207,6 +207,7 @@ public: void CheckObjectLiteralKeys(const ArenaVector &properties); Type *BuildBasicClassProperties(ir::ClassDefinition *classDef); ETSObjectType *BuildAnonymousClassProperties(ir::ClassDefinition *classDef, ETSObjectType *superType); + Type *MaybeGradualType(ir::AstNode *node, ETSObjectType *type); Type *BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl); ETSObjectType *GetSuperType(ETSObjectType *type); ArenaVector GetInterfaces(ETSObjectType *type); diff --git a/ets2panda/checker/ets/object.cpp b/ets2panda/checker/ets/object.cpp index c72441cdc6..6c7a77a104 100644 --- a/ets2panda/checker/ets/object.cpp +++ b/ets2panda/checker/ets/object.cpp @@ -457,6 +457,15 @@ void ETSChecker::CreateTypeForClassOrInterfaceTypeParameters(ETSObjectType *type type->AddObjectFlag(ETSObjectFlags::INCOMPLETE_INSTANTIATION); } +Type *ETSChecker::MaybeGradualType(ir::AstNode *node, ETSObjectType *type) +{ + ES2PANDA_ASSERT(node->IsClassDefinition() || node->IsTSInterfaceDeclaration()); + auto isDynamic = node->IsClassDefinition() ? node->AsClassDefinition()->Language().IsDynamic() + : node->AsTSInterfaceDeclaration()->Language().IsDynamic(); + // Temporary solution, the struct loses 'language' while being converted to a class through the plugin API. + return isDynamic || Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(type) : type; +} + Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *interfaceDecl) { auto *var = interfaceDecl->Id()->Variable(); @@ -470,11 +479,11 @@ Type *ETSChecker::BuildBasicInterfaceProperties(ir::TSInterfaceDeclaration *inte if (var->TsType() == nullptr) { interfaceType = CreateETSObjectTypeOrBuiltin(interfaceDecl, checker::ETSObjectFlags::INTERFACE); interfaceType->SetVariable(var); - type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; + type = MaybeGradualType(interfaceDecl, interfaceType); var->SetTsType(type); } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { interfaceType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); - type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(interfaceType) : interfaceType; + type = MaybeGradualType(interfaceDecl, interfaceType); } else { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); @@ -523,7 +532,7 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) checker::Type *type {}; if (var->TsType() == nullptr) { classType = CreateETSObjectTypeOrBuiltin(classDef, checker::ETSObjectFlags::CLASS); - type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(classType) : classType; + type = MaybeGradualType(classDef, classType); classType->SetVariable(var); var->SetTsType(type); if (classDef->IsAbstract()) { @@ -531,7 +540,7 @@ Type *ETSChecker::BuildBasicClassProperties(ir::ClassDefinition *classDef) } } else if (var->TsType()->MaybeBaseTypeOfGradualType()->IsETSObjectType()) { classType = var->TsType()->MaybeBaseTypeOfGradualType()->AsETSObjectType(); - type = Program()->IsDeclForDynamicStaticInterop() ? CreateGradualType(classType) : classType; + type = MaybeGradualType(classDef, classType); } else { ES2PANDA_ASSERT(IsAnyError()); return GlobalTypeError(); diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index ef96e14125..dc82b22e2d 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -89,7 +89,8 @@ bool ETSChecker::CheckNonNullish(ir::Expression const *expr) Type *ETSChecker::GetNonNullishType(Type *type) { if (type->IsGradualType()) { - return GetNonNullishType(type->AsGradualType()->GetBaseType()); + return CreateGradualType(GetNonNullishType(type->AsGradualType()->GetBaseType()), + type->AsGradualType()->Language()); } if (type->DefinitelyNotETSNullish()) { return type; diff --git a/ets2panda/checker/ets/utilityTypeHandlers.cpp b/ets2panda/checker/ets/utilityTypeHandlers.cpp index 0224e9882e..74dca5cdc9 100644 --- a/ets2panda/checker/ets/utilityTypeHandlers.cpp +++ b/ets2panda/checker/ets/utilityTypeHandlers.cpp @@ -1058,7 +1058,7 @@ Type *ETSChecker::HandleRequiredType(Type *typeToBeRequired) typeToBeRequired = typeToBeRequired->Clone(this); - MakePropertiesNonNullish(typeToBeRequired->AsETSObjectType()); + MakePropertiesNonNullish(typeToBeRequired->MaybeBaseTypeOfGradualType()->AsETSObjectType()); return typeToBeRequired; } diff --git a/ets2panda/checker/types/ets/etsAnyType.cpp b/ets2panda/checker/types/ets/etsAnyType.cpp index 52793689c9..8f36fb2b21 100644 --- a/ets2panda/checker/types/ets/etsAnyType.cpp +++ b/ets2panda/checker/types/ets/etsAnyType.cpp @@ -105,6 +105,6 @@ void ETSAnyType::ToDebugInfoType(std::stringstream &ss) const Type *ETSAnyType::Instantiate(ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, [[maybe_unused]] GlobalTypesHolder *globalTypes) { - return allocator->New(); + return isRelaxedAny_ ? allocator->New(true) : allocator->New(); } } // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/gradualType.cpp b/ets2panda/checker/types/gradualType.cpp index 8a80baa2a9..ccf3f35b6c 100644 --- a/ets2panda/checker/types/gradualType.cpp +++ b/ets2panda/checker/types/gradualType.cpp @@ -21,37 +21,64 @@ namespace ark::es2panda::checker { void GradualType::Identical(TypeRelation *relation, Type *other) { - baseType_->Identical(relation, other); + if (other->IsGradualType()) { + baseType_->Identical(relation, other->AsGradualType()->GetBaseType()); + } else { + baseType_->Identical(relation, other); + } } void GradualType::AssignmentTarget(TypeRelation *relation, Type *source) { - baseType_->AssignmentTarget(relation, source); + if (source->IsGradualType()) { + baseType_->AssignmentTarget(relation, source->AsGradualType()->GetBaseType()); + } else { + baseType_->AssignmentTarget(relation, source); + } } bool GradualType::AssignmentSource(TypeRelation *relation, Type *target) { + if (target->IsGradualType()) { + return baseType_->AssignmentSource(relation, target->AsGradualType()->GetBaseType()); + } return baseType_->AssignmentSource(relation, target); } void GradualType::Compare(TypeRelation *relation, Type *other) { - return baseType_->Compare(relation, other); + if (other->IsGradualType()) { + baseType_->Compare(relation, other->AsGradualType()->GetBaseType()); + } else { + baseType_->Compare(relation, other); + } } void GradualType::Cast(TypeRelation *relation, Type *target) { - return baseType_->Cast(relation, target); + if (target->IsGradualType()) { + baseType_->Cast(relation, target->AsGradualType()->GetBaseType()); + } else { + baseType_->Cast(relation, target); + } } void GradualType::CastTarget(TypeRelation *relation, Type *source) { - return baseType_->CastTarget(relation, source); + if (source->IsGradualType()) { + baseType_->CastTarget(relation, source->AsGradualType()->GetBaseType()); + } else { + baseType_->CastTarget(relation, source); + } } void GradualType::IsSubtypeOf(TypeRelation *relation, Type *target) { - return baseType_->IsSubtypeOf(relation, target); + if (target->IsGradualType()) { + baseType_->IsSubtypeOf(relation, target->AsGradualType()->GetBaseType()); + } else { + baseType_->IsSubtypeOf(relation, target); + } } void GradualType::IsSupertypeOf(TypeRelation *relation, Type *source) diff --git a/ets2panda/compiler/core/ETSCompiler.cpp b/ets2panda/compiler/core/ETSCompiler.cpp index 15549ccb50..75fd7d3de5 100644 --- a/ets2panda/compiler/core/ETSCompiler.cpp +++ b/ets2panda/compiler/core/ETSCompiler.cpp @@ -708,8 +708,7 @@ void ETSCompiler::CompileAny(const ir::CallExpression *expr, const ir::Expressio } else { etsg->CallAnyThis(expr, memberExpr->Property()->AsIdentifier(), expr->Arguments(), objReg); } - auto returnType = expr->Signature()->ReturnType(); - etsg->EmitAnyCheckCast(expr, returnType); + etsg->EmitAnyCheckCast(expr, expr->TsType()); } void ETSCompiler::EmitCall(const ir::CallExpression *expr, compiler::VReg &calleeReg, diff --git a/ets2panda/compiler/lowering/ets/enumLowering.cpp b/ets2panda/compiler/lowering/ets/enumLowering.cpp index 40db4f3e63..8db2e4c678 100644 --- a/ets2panda/compiler/lowering/ets/enumLowering.cpp +++ b/ets2panda/compiler/lowering/ets/enumLowering.cpp @@ -308,7 +308,7 @@ ir::ClassDeclaration *EnumLoweringPhase::CreateClass(ir::TSEnumDeclaration *cons Allocator(), ident, flags.isLocal ? baseClassDefinitionFlag | ir::ClassDefinitionModifiers::LOCAL : baseClassDefinitionFlag, enumDecl->IsDeclare() ? ir::ModifierFlags::FINAL | ir::ModifierFlags::DECLARE : ir::ModifierFlags::FINAL, - Language(Language::Id::ETS)); + enumDecl->Language()); classDef->SetSuper(superClass); auto *classDecl = AllocNode(classDef, Allocator()); diff --git a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp index ce9840672b..e2d6d9405d 100644 --- a/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp +++ b/ets2panda/compiler/lowering/ets/gradualTypeNarrowing.cpp @@ -89,6 +89,10 @@ void GradualTypeNarrowing::NarrowGradualType(ir::AstNode *node) if (typedNode->TsType() != nullptr) { typedNode->SetTsType(TransformType(typedNode->TsType(), typeTransformFunc)); } + if (typedNode->IsBinaryExpression()) { + typedNode->AsBinaryExpression()->SetOperationType( + TransformType(typedNode->AsBinaryExpression()->OperationType(), typeTransformFunc)); + } auto var = node->Variable(); if (var != nullptr && var->TsType() != nullptr) { diff --git a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp index 1e4f5046a9..4998efb733 100644 --- a/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/interfaceObjectLiteralLowering.cpp @@ -35,13 +35,13 @@ std::string_view InterfaceObjectLiteralLowering::Name() const static inline bool IsInterfaceType(const checker::Type *type) { return type != nullptr && type->IsETSObjectType() && - type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE) && !type->IsETSAnyType(); + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::INTERFACE) && !type->IsGradualType(); } static inline bool IsAbstractClassType(const checker::Type *type) { return type != nullptr && type->IsETSObjectType() && - type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && !type->IsETSAnyType(); + type->AsETSObjectType()->HasObjectFlag(checker::ETSObjectFlags::ABSTRACT) && !type->IsGradualType(); } static ir::AstNode *CreateAnonClassImplCtor(public_lib::Context *ctx, ArenaVector &readonlyFields) diff --git a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp index 9fcd05a2db..2e0b7f8328 100644 --- a/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp +++ b/ets2panda/compiler/lowering/ets/objectIndexAccess.cpp @@ -116,7 +116,7 @@ bool ObjectIndexLowering::PerformForModule(public_lib::Context *ctx, parser::Pro auto memberExpr = ast->AsAssignmentExpression()->Left()->AsMemberExpression(); if (memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && memberExpr->AsMemberExpression()->ObjType() != nullptr && - !memberExpr->Object()->TsType()->IsETSAnyType()) { + !memberExpr->Object()->TsType()->IsGradualType()) { return ProcessIndexSetAccess(parser, checker, ast->AsAssignmentExpression()); } } @@ -130,7 +130,7 @@ bool ObjectIndexLowering::PerformForModule(public_lib::Context *ctx, parser::Pro if (ast->IsMemberExpression()) { auto memberExpr = ast->AsMemberExpression(); if (memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && - memberExpr->ObjType() != nullptr && !memberExpr->Object()->TsType()->IsETSAnyType()) { + memberExpr->ObjType() != nullptr && !memberExpr->Object()->TsType()->IsGradualType()) { return ProcessIndexGetAccess(parser, checker, ast->AsMemberExpression()); } } @@ -148,7 +148,7 @@ bool ObjectIndexLowering::PostconditionForModule([[maybe_unused]] public_lib::Co if (ast->IsMemberExpression()) { auto memberExpr = ast->AsMemberExpression(); if (memberExpr->Kind() == ir::MemberExpressionKind::ELEMENT_ACCESS && memberExpr->ObjType() != nullptr && - !memberExpr->Object()->TsType()->IsETSAnyType()) { + !memberExpr->Object()->TsType()->IsGradualType()) { return true; } } diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index 6318267b06..b593f51c3e 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -309,15 +309,25 @@ static ir::AstNode *HandleDynamicObjectLiteralLowering(public_lib::Context *ctx, std::stringstream ss; ArenaVector blockStatements(allocator->Adapter()); - auto gensym = GenName(allocator); - blockStatements.push_back( - parser->CreateFormattedStatement("let @@I1:ESValue = ESValue.instantiateEmptyObject()", gensym)); + std::vector args; + auto gensym = Gensym(allocator); + blockStatements.push_back(parser->CreateFormattedStatement("let @@I1:ESValue = ESValue.instantiateEmptyObject();", + gensym->Clone(allocator, nullptr))); + size_t counter = 0; for (auto property : objExpr->Properties()) { - ss << "@@I1.setProperty('" + property->AsProperty()->Key()->DumpEtsSrc() + "', ESValue.wrap(" + - property->AsProperty()->Value()->DumpEtsSrc() + "))"; + auto appendArgument = [&](auto &&arg) { + args.push_back(std::forward(arg)); + return ++counter; + }; + + const size_t genSymId = appendArgument(gensym->Clone(allocator, nullptr)); + const size_t valueId = appendArgument(property->AsProperty()->Value()->Clone(allocator, nullptr)); + + ss << "@@I" << genSymId << ".setProperty('" << property->AsProperty()->Key()->DumpEtsSrc() + << "', ESValue.wrap(@@E" << valueId << "));"; } - blockStatements.push_back(parser->CreateFormattedStatement(ss.str(), gensym)); - blockStatements.push_back(parser->CreateFormattedStatement("@@I1", gensym)); + blockStatements.push_back(parser->CreateFormattedStatement(ss.str(), args)); + blockStatements.push_back(parser->CreateFormattedStatement("@@I1.unwrap();", gensym->Clone(allocator, nullptr))); auto *blockExpr = util::NodeAllocator::ForceSetParent(allocator, std::move(blockStatements)); blockExpr->SetParent(objExpr->Parent()); CheckLoweredNode(varBinder, checker, blockExpr); @@ -336,10 +346,9 @@ bool ObjectLiteralLowering::PerformForModule(public_lib::Context *ctx, parser::P return ast; } if (exprType->IsETSObjectType()) { - return HandleObjectLiteralLowering(ctx, ast->AsObjectExpression()); - } - if (exprType->IsETSAnyType()) { - return HandleDynamicObjectLiteralLowering(ctx, ast->AsObjectExpression()); + return exprType->AsETSObjectType()->GetDeclNode()->AsTyped()->TsType()->IsGradualType() + ? HandleDynamicObjectLiteralLowering(ctx, ast->AsObjectExpression()) + : HandleObjectLiteralLowering(ctx, ast->AsObjectExpression()); } } return ast; diff --git a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp index 77adc2ac37..63ee341389 100644 --- a/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp +++ b/ets2panda/compiler/lowering/ets/topLevelStmts/globalClassHandler.cpp @@ -161,9 +161,9 @@ ir::ClassDeclaration *GlobalClassHandler::CreateTransformedClass(ir::ETSModule * auto *ident = NodeAllocator::Alloc(allocator_, className, allocator_); ident->SetRange(ns->Ident()->Range()); - auto *classDef = NodeAllocator::Alloc( - allocator_, allocator_, ident, ir::ClassDefinitionModifiers::CLASS_DECL, ir::ModifierFlags::ABSTRACT, - Language(Language::Id::ETS)); + auto *classDef = NodeAllocator::Alloc(allocator_, allocator_, ident, + ir::ClassDefinitionModifiers::CLASS_DECL, + ir::ModifierFlags::ABSTRACT, ns->Language()); ES2PANDA_ASSERT(classDef != nullptr); classDef->SetRange(ns->Range()); classDef->AddModifier(ns->Modifiers()); diff --git a/ets2panda/compiler/lowering/phase.cpp b/ets2panda/compiler/lowering/phase.cpp index 6c49ef813b..bc06d4dca0 100644 --- a/ets2panda/compiler/lowering/phase.cpp +++ b/ets2panda/compiler/lowering/phase.cpp @@ -132,7 +132,6 @@ std::vector GetETSPhaseList() new PluginPhase {g_pluginsAfterCheck, ES2PANDA_STATE_CHECKED, &util::Plugin::AfterCheck}, // new ConvertPrimitiveCastMethodCall, new DynamicImport, - new GradualTypeNarrowing, new AnnotationCopyPostLowering, new AsyncMethodLowering, new DeclareOverloadLowering, @@ -161,6 +160,7 @@ std::vector GetETSPhaseList() new OptionalArgumentsLowering, // #22952 could be moved to earlier phase new GenericBridgesPhase, new TypeFromLowering, + new GradualTypeNarrowing, new PrimitiveConversionPhase, new UnboxPhase, // pluginsAfterLowerings has to come at the very end, nothing should go after it diff --git a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp index 501927fd03..b7f476f679 100644 --- a/ets2panda/evaluate/scopedDebugInfoPlugin.cpp +++ b/ets2panda/evaluate/scopedDebugInfoPlugin.cpp @@ -409,8 +409,9 @@ parser::Program *ScopedDebugInfoPlugin::CreateEmptyProgram(std::string_view sour program->SetSource({sourceFilePath, "", globalProgram_->SourceFileFolder().Utf8(), true, false}); program->SetPackageInfo(moduleName, util::ModuleKind::MODULE); auto *emptyIdent = allocator->New("", allocator); + auto lang = program->IsDeclForDynamicStaticInterop() ? Language(Language::Id::JS) : Language(Language::Id::ETS); auto *etsModule = allocator->New(allocator, ArenaVector(allocator->Adapter()), - emptyIdent, ir::ModuleFlag::ETSSCRIPT, program); + emptyIdent, ir::ModuleFlag::ETSSCRIPT, lang, program); program->SetAst(etsModule); helpers::AddExternalProgram(globalProgram_, program, moduleName); diff --git a/ets2panda/ir/ets/etsModule.cpp b/ets2panda/ir/ets/etsModule.cpp index 4891a53166..7c8faf7945 100644 --- a/ets2panda/ir/ets/etsModule.cpp +++ b/ets2panda/ir/ets/etsModule.cpp @@ -57,7 +57,7 @@ void ETSModule::Dump(ir::SrcDumper *dumper) const ETSModule *ETSModule::Construct(ArenaAllocator *allocator) { ArenaVector statementList(allocator->Adapter()); - return allocator->New(allocator, std::move(statementList), nullptr, ModuleFlag::NONE, nullptr); + return allocator->New(allocator, std::move(statementList), nullptr, ModuleFlag::NONE, lang_, nullptr); } void ETSModule::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ets/etsModule.h b/ets2panda/ir/ets/etsModule.h index 8f2bb0ecd8..cfa7c5a05d 100644 --- a/ets2panda/ir/ets/etsModule.h +++ b/ets2panda/ir/ets/etsModule.h @@ -46,11 +46,13 @@ namespace ark::es2panda::ir { class ETSModule : public JsDocAllowed> { public: + // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit ETSModule(ArenaAllocator *allocator, ArenaVector &&statementList, Identifier *ident, - ModuleFlag flag, parser::Program *program) + ModuleFlag flag, Language lang, parser::Program *program) : JsDocAllowed>(allocator, std::move(statementList)), ident_(ident), flag_(flag), + lang_(lang), program_(program) { type_ = AstNodeType::ETS_MODULE; @@ -59,10 +61,11 @@ public: // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit ETSModule(ArenaAllocator *allocator, ArenaVector &&statementList, Identifier *ident, - ModuleFlag flag, parser::Program *program, AstNodeHistory *history) + ModuleFlag flag, Language lang, parser::Program *program, AstNodeHistory *history) : JsDocAllowed>(allocator, std::move(statementList)), ident_(ident), flag_(flag), + lang_(lang), program_(program) { type_ = AstNodeType::ETS_MODULE; @@ -93,6 +96,11 @@ public: return GetHistoryNodeAs()->globalClass_; } + [[nodiscard]] es2panda::Language Language() const noexcept + { + return GetHistoryNodeAs()->lang_; + } + ir::ClassDefinition *GlobalClass() { return GetHistoryNodeAs()->globalClass_; @@ -162,6 +170,7 @@ private: Identifier *ident_; ModuleFlag flag_; + es2panda::Language lang_; parser::Program *program_; ir::ClassDefinition *globalClass_ {}; }; diff --git a/ets2panda/ir/ts/tsEnumDeclaration.cpp b/ets2panda/ir/ts/tsEnumDeclaration.cpp index c3d9c28f02..93e14b5f32 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.cpp +++ b/ets2panda/ir/ts/tsEnumDeclaration.cpp @@ -191,7 +191,7 @@ TSEnumDeclaration *TSEnumDeclaration::Construct(ArenaAllocator *allocator) { ArenaVector members(allocator->Adapter()); return allocator->New(allocator, nullptr, std::move(members), - ConstructorFlags {false, false, false}); + ConstructorFlags {false, false, false}, lang_); } void TSEnumDeclaration::CopyTo(AstNode *other) const diff --git a/ets2panda/ir/ts/tsEnumDeclaration.h b/ets2panda/ir/ts/tsEnumDeclaration.h index 5d3cb3dad2..2a992d9c39 100644 --- a/ets2panda/ir/ts/tsEnumDeclaration.h +++ b/ets2panda/ir/ts/tsEnumDeclaration.h @@ -39,13 +39,14 @@ public: // NOLINTEND(cppcoreguidelines-pro-type-member-init) explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector &&members, - ConstructorFlags &&flags) + ConstructorFlags &&flags, Language lang) : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), decorators_(allocator->Adapter()), key_(key), typeNode_(nullptr), members_(std::move(members)), - isConst_(flags.isConst) + isConst_(flags.isConst), + lang_(lang) { if (flags.isStatic) { AddModifier(ModifierFlags::STATIC); @@ -55,14 +56,16 @@ public: } } + // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector &&members, - ConstructorFlags &&flags, ir::TypeNode *typeNode) + ConstructorFlags &&flags, ir::TypeNode *typeNode, Language lang) : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), decorators_(allocator->Adapter()), key_(key), typeNode_(typeNode), members_(std::move(members)), - isConst_(flags.isConst) + isConst_(flags.isConst), + lang_(lang) { if (flags.isStatic) { AddModifier(ModifierFlags::STATIC); @@ -73,14 +76,16 @@ public: InitHistory(); } + // CC-OFFNXT(G.FUN.01-CPP) solid logic explicit TSEnumDeclaration(ArenaAllocator *allocator, Identifier *key, ArenaVector &&members, - ConstructorFlags &&flags, AstNodeHistory *history) + ConstructorFlags &&flags, Language lang, AstNodeHistory *history) : TypedStatement(AstNodeType::TS_ENUM_DECLARATION), decorators_(allocator->Adapter()), key_(key), typeNode_(nullptr), members_(std::move(members)), - isConst_(flags.isConst) + isConst_(flags.isConst), + lang_(lang) { if (flags.isStatic) { AddModifier(ModifierFlags::STATIC); @@ -171,6 +176,11 @@ public: return !inTs; } + [[nodiscard]] es2panda::Language Language() const noexcept + { + return GetHistoryNodeAs()->lang_; + } + static varbinder::EnumMemberResult EvaluateEnumMember(checker::TSChecker *checker, varbinder::EnumVariable *enumVar, const ir::AstNode *expr); void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; @@ -213,6 +223,7 @@ private: util::StringView internalName_; ir::ClassDefinition *boxedClass_ {nullptr}; bool isConst_; + es2panda::Language lang_; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/ir/ts/tsInterfaceDeclaration.h b/ets2panda/ir/ts/tsInterfaceDeclaration.h index 64e6a30e70..217a31c5b6 100644 --- a/ets2panda/ir/ts/tsInterfaceDeclaration.h +++ b/ets2panda/ir/ts/tsInterfaceDeclaration.h @@ -177,7 +177,7 @@ public: void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; - es2panda::Language Language() const + [[nodiscard]] es2panda::Language Language() const noexcept { return GetHistoryNodeAs()->lang_; } diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index 9e2059c27d..1d81f70299 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -180,8 +180,8 @@ ir::ETSModule *ETSParser::ParseETSGlobalScript(lexer::SourcePosition startLoc, A etsnolintParser.ApplyETSNolintsToStatements(statements); auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); - auto *etsModule = - AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, + GetContext().GetLanguage(), GetProgram()); ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; @@ -202,8 +202,8 @@ ir::ETSModule *ETSParser::ParseImportsAndReExportOnly(lexer::SourcePosition star etsnolintParser.ApplyETSNolintsToStatements(statements); auto ident = AllocNode(compiler::Signatures::ETS_GLOBAL, Allocator()); - auto *etsModule = - AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, GetProgram()); + auto *etsModule = AllocNode(Allocator(), std::move(statements), ident, ir::ModuleFlag::ETSSCRIPT, + GetContext().GetLanguage(), GetProgram()); ES2PANDA_ASSERT(etsModule != nullptr); etsModule->SetRange({startLoc, Lexer()->GetToken().End()}); return etsModule; @@ -321,8 +321,10 @@ void ETSParser::AddGenExtenralSourceToParseList(public_lib::Context *ctx) auto allocator = ctx->allocator; auto ident = allocator->New(compiler::Signatures::ETS_GLOBAL, allocator); ArenaVector stmts(allocator->Adapter()); - auto etsModule = allocator->New(allocator, std::move(stmts), ident, ir::ModuleFlag::ETSSCRIPT, - ctx->parserProgram); + + auto etsModule = + allocator->New(allocator, std::move(stmts), ident, ir::ModuleFlag::ETSSCRIPT, + ctx->parser->AsETSParser()->GetContext().GetLanguage(), ctx->parserProgram); ctx->parserProgram->SetAst(etsModule); for (auto &sourceName : ctx->sourceFileNames) { util::ImportPathManager::ImportMetadata importData {util::ImportFlags::NONE}; diff --git a/ets2panda/parser/ETSparserEnums.cpp b/ets2panda/parser/ETSparserEnums.cpp index 4e6b8d9361..56be9b2749 100644 --- a/ets2panda/parser/ETSparserEnums.cpp +++ b/ets2panda/parser/ETSparserEnums.cpp @@ -192,11 +192,13 @@ ir::TSEnumDeclaration *ETSParser::ParseEnumMembers(ir::Identifier *const key, co if (typeAnnotation == nullptr) { enumDeclaration = AllocNode( Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}); + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, + GetContext().GetLanguage()); } else { enumDeclaration = AllocNode( Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, typeAnnotation); + ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, InAmbientContext()}, typeAnnotation, + GetContext().GetLanguage()); } ES2PANDA_ASSERT(enumDeclaration != nullptr); diff --git a/ets2panda/parser/ETSparserNamespaces.cpp b/ets2panda/parser/ETSparserNamespaces.cpp index d3ecaeedf6..d60297de79 100644 --- a/ets2panda/parser/ETSparserNamespaces.cpp +++ b/ets2panda/parser/ETSparserNamespaces.cpp @@ -68,15 +68,17 @@ ir::Statement *ETSParser::ParseNamespace(ir::ModifierFlags flags) ir::ETSModule *ETSParser::ParseNamespaceImp(ir::ModifierFlags flags) { Lexer()->NextToken(); - auto *result = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), - ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, globalProgram_); + auto *result = + AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), ExpectIdentifier(), + ir::ModuleFlag::NAMESPACE, GetContext().GetLanguage(), globalProgram_); ir::ETSModule *parent = result; ir::ETSModule *child = nullptr; while (Lexer()->GetToken().Type() == lexer::TokenType::PUNCTUATOR_PERIOD) { Lexer()->NextToken(); auto start = Lexer()->GetToken().Start(); child = AllocNode(Allocator(), ArenaVector(Allocator()->Adapter()), - ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, globalProgram_); + ExpectIdentifier(), ir::ModuleFlag::NAMESPACE, GetContext().GetLanguage(), + globalProgram_); ES2PANDA_ASSERT(child != nullptr); child->SetParent(parent); child->SetRange({start, Lexer()->GetToken().Start()}); diff --git a/ets2panda/parser/TypedParser.cpp b/ets2panda/parser/TypedParser.cpp index cc626c2ed9..555435eb53 100644 --- a/ets2panda/parser/TypedParser.cpp +++ b/ets2panda/parser/TypedParser.cpp @@ -711,8 +711,9 @@ ir::TSEnumDeclaration *TypedParser::ParseEnumMembers(ir::Identifier *key, const }, &endLoc, true); - auto *enumDeclaration = AllocNode(Allocator(), key, std::move(members), - ir::TSEnumDeclaration::ConstructorFlags {isConst}); + auto *enumDeclaration = + AllocNode(Allocator(), key, std::move(members), + ir::TSEnumDeclaration::ConstructorFlags {isConst}, GetContext().GetLanguage()); ES2PANDA_ASSERT(enumDeclaration != nullptr); enumDeclaration->SetRange({enumStart, endLoc}); diff --git a/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets new file mode 100644 index 0000000000..2f6e3285bf --- /dev/null +++ b/ets2panda/test/ast/parser/ets/dynamic_import_tests/dynamic_type_import.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024-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. + */ + +/*--- +flags: [dynamic-ast] +---*/ + +import { C, requiredC } from "dynamic_import_tests/modules/module" + +class A { + f?: A = new A() // should be ok +} + +function foo(c: C) { } + +foo({ s: "" }) // should be ok diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import.ets b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import.ets index 84d15d545c..e804c6bee5 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import.ets +++ b/ets2panda/test/parser/ets/dynamic_import_tests/dynamic_decl_import.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2025 Huawei Device Co., Ltd. + * 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 diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt index 409dcee411..80776238e5 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module-expected.txt @@ -2105,8 +2105,8 @@ "program": "module.ets" }, "end": { - "line": 37, - "column": 2, + "line": 39, + "column": 7, "program": "module.ets" } } @@ -2118,8 +2118,393 @@ "program": "module.ets" }, "end": { - "line": 37, - "column": 2, + "line": 39, + "column": 7, + "program": "module.ets" + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 22, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 23, + "program": "module.ets" + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "s", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 40, + "column": 6, + "program": "module.ets" + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": true, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 40, + "column": 13, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 41, + "column": 2, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 40, + "column": 7, + "program": "module.ets" + }, + "end": { + "line": 41, + "column": 2, + "program": "module.ets" + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 40, + "column": 5, + "program": "module.ets" + }, + "end": { + "line": 41, + "column": 2, + "program": "module.ets" + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 25, + "program": "module.ets" + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 39, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 25, + "program": "module.ets" + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 39, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 25, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 25, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 25, + "program": "module.ets" + }, + "end": { + "line": 39, + "column": 25, + "program": "module.ets" + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1, + "program": null + }, + "end": { + "line": 1, + "column": 1, + "program": null + } + } + } + ], + "loc": { + "start": { + "line": 39, + "column": 24, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 7, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 39, + "column": 16, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 7, + "program": "module.ets" + } + } + }, + { + "type": "TSTypeAliasDeclaration", + "id": { + "type": "Identifier", + "name": "requiredC", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 21, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 30, + "program": "module.ets" + } + } + }, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Required", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 33, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 41, + "program": "module.ets" + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 43, + "column": 42, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 43, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 42, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 42, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, + "program": "module.ets" + } + } + } + ], + "loc": { + "start": { + "line": 43, + "column": 41, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 33, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 33, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, + "program": "module.ets" + } + } + }, + "loc": { + "start": { + "line": 43, + "column": 16, + "program": "module.ets" + }, + "end": { + "line": 43, + "column": 44, "program": "module.ets" } } @@ -2706,8 +3091,8 @@ "program": "module.ets" }, "end": { - "line": 37, - "column": 2, + "line": 43, + "column": 44, "program": "module.ets" } } diff --git a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets index 500594f817..09a107ab63 100644 --- a/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets +++ b/ets2panda/test/parser/ets/dynamic_import_tests/modules/module.ets @@ -34,4 +34,10 @@ export declare interface I { export declare abstract class Animal { abstract move(): void -} \ No newline at end of file +} + +export declare class C { + s:string +} + +export declare type requiredC = Required \ No newline at end of file diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iii.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iii.cpp index 399a739853..1ea9c92388 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iii.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iii.cpp @@ -22,7 +22,7 @@ TEST_F(PluginConversionRuleUnitTest, ParserProgramPtrInputParameter) { std::string targetCAPI {R"( /* explicit ETSModule(ArenaAllocator *allocator, ArenaVector &&statementList, Identifier *ident, - ModuleFlag flag, parser::Program *program) */ + ModuleFlag flag, Language lang, parser::Program *program) */ extern "C" es2panda_AstNode *CreateETSModule([[maybe_unused]] es2panda_Context *context, [[maybe_unused]] es2panda_AstNode **statementList, size_t statementListLen, [[maybe_unused]] es2panda_AstNode *ident, [[maybe_unused]] Es2pandaModuleFlag flag, @@ -39,11 +39,12 @@ TEST_F(PluginConversionRuleUnitTest, ParserProgramPtrInputParameter) } auto *identE2p = reinterpret_cast(ident); auto flagE2p = E2pToIrModuleFlag(flag); + ark::es2panda::Language langE2p {Language::Id::ETS}; auto *programE2p = reinterpret_cast(program); auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; auto *astNode = (ctxAllocator->New(allocatorE2p, std::move(statementListArenaVector), - identE2p, flagE2p, programE2p)); + identE2p, flagE2p, langE2p, programE2p)); astNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); return reinterpret_cast(astNode); })"}; diff --git a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iv.cpp b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iv.cpp index 97046535e4..e1d8514256 100644 --- a/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iv.cpp +++ b/ets2panda/test/unit/plugin_conversion_rule/plugin_conversion_rule_part_iv.cpp @@ -395,17 +395,19 @@ TEST_F(PluginConversionRuleUnitTest, TSEnumDeclarationConstructorFlagsInputParam auto *allocatorE2p = reinterpret_cast(context)->allocator; auto *keyE2p = reinterpret_cast(key); ArenaVector membersArenaVector {reinterpret_cast(context)->allocator->Adapter()}; - for (size_t i = 0; i < membersLen; ++i) { - auto *membersElement1 = members[i]; - auto *membersElement1E2p = reinterpret_cast(membersElement1); - - membersArenaVector.push_back(membersElement1E2p); - } + for (size_t i = 0; i < membersLen; ++i) { + auto *membersElement1 = members[i]; + auto *membersElement1E2p = reinterpret_cast(membersElement1); + membersArenaVector.push_back(membersElement1E2p); + } + + ark::es2panda::Language langE2p {Language::Id::ETS}; auto *ctx = reinterpret_cast(context); auto *ctxAllocator = ctx->allocator; auto *astNode = (ctxAllocator->New(allocatorE2p, keyE2p, - std::move(membersArenaVector), ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, isDeclare})); + std::move(membersArenaVector), ir::TSEnumDeclaration::ConstructorFlags {isConst, isStatic, isDeclare}, + langE2p)); astNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); return reinterpret_cast(astNode); })"}; diff --git a/ets2panda/util/ast-builders/tsEnumDeclarationBuilder.h b/ets2panda/util/ast-builders/tsEnumDeclarationBuilder.h index bd123fffb2..b5dd0a93de 100644 --- a/ets2panda/util/ast-builders/tsEnumDeclarationBuilder.h +++ b/ets2panda/util/ast-builders/tsEnumDeclarationBuilder.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -62,7 +62,8 @@ public: TSEnumDeclaration *Build() { auto node = AllocNode(Allocator(), key_, std::move(members_), - ir::TSEnumDeclaration::ConstructorFlags {isConst_, isStatic_, isDeclare_}); + ir::TSEnumDeclaration::ConstructorFlags {isConst_, isStatic_, isDeclare_}, + Language(Language::Id::ETS)); return node; } -- Gitee From 66aa630a938e6d53573bb184c46259e87f8b2c87 Mon Sep 17 00:00:00 2001 From: oh_ci Date: Thu, 10 Jul 2025 04:01:31 +0000 Subject: [PATCH 080/107] =?UTF-8?q?=E5=9B=9E=E9=80=80=20'Pull=20Request=20?= =?UTF-8?q?!5992=20:=20Cancel=20detection=20of=20unused=20tools=20when=20e?= =?UTF-8?q?nableDecl'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ets2panda/driver/build_system/src/build/base_mode.ts | 10 ++++++---- .../driver/build_system/src/build/declgen_worker.ts | 11 +++++------ .../build_system/src/init/process_build_config.ts | 4 ++-- ets2panda/driver/build_system/src/types.ts | 1 - 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index e6de447af6..93a3e9b220 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -106,7 +106,6 @@ export abstract class BaseMode { public hasCleanWorker: boolean; public byteCodeHar: boolean; public es2pandaMode: number; - public skipDeclCheck: boolean; constructor(buildConfig: BuildConfig) { this.buildConfig = buildConfig; @@ -143,7 +142,6 @@ export abstract class BaseMode { this.hasCleanWorker = false; this.byteCodeHar = buildConfig.byteCodeHar as boolean; this.es2pandaMode = buildConfig?.es2pandaMode ?? 0; - this.skipDeclCheck = buildConfig?.skipDeclCheck as boolean ?? true; } public declgen(fileInfo: CompileFileInfo): void { @@ -176,13 +174,13 @@ export abstract class BaseMode { arktsGlobal.compilerContext = arkts.Context.createFromString(source); PluginDriver.getInstance().getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, this.skipDeclCheck); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, true); let ast = arkts.EtsScript.fromContext(); PluginDriver.getInstance().getPluginContext().setArkTSAst(ast); PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, this.skipDeclCheck); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, true); ast = arkts.EtsScript.fromContext(); PluginDriver.getInstance().getPluginContext().setArkTSAst(ast); @@ -695,6 +693,10 @@ export abstract class BaseMode { protected collectCompileFiles(): void { this.entryFiles.forEach((file: string) => { + // Skip the declaration files when compiling abc + if (file.endsWith(DECL_ETS_SUFFIX)) { + return; + } for (const [packageName, moduleInfo] of this.moduleInfos) { const relativePath = path.relative(moduleInfo.moduleRootPath, file); if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) { diff --git a/ets2panda/driver/build_system/src/build/declgen_worker.ts b/ets2panda/driver/build_system/src/build/declgen_worker.ts index 5a32a7f000..872eb49db1 100644 --- a/ets2panda/driver/build_system/src/build/declgen_worker.ts +++ b/ets2panda/driver/build_system/src/build/declgen_worker.ts @@ -18,7 +18,7 @@ import { BuildConfig } from '../types'; import { Logger } from '../logger'; import * as fs from 'fs'; import * as path from 'path'; -import { changeDeclgenFileExtension, ensurePathExists } from '../utils'; +import { changeFileExtension, ensurePathExists } from '../utils'; import { DECL_ETS_SUFFIX, TS_SUFFIX, @@ -56,13 +56,13 @@ process.on('message', (message: { moduleInfo.packageName, filePathFromModuleRoot ); - declEtsOutputPath = changeDeclgenFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX); + declEtsOutputPath = changeFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX); let etsOutputPath: string = path.join( moduleInfo.declgenBridgeCodePath as string, moduleInfo.packageName, filePathFromModuleRoot ); - etsOutputPath = changeDeclgenFileExtension(etsOutputPath, TS_SUFFIX); + etsOutputPath = changeFileExtension(etsOutputPath, TS_SUFFIX); ensurePathExists(declEtsOutputPath); ensurePathExists(etsOutputPath); @@ -78,15 +78,14 @@ process.on('message', (message: { ]).peer; arktsGlobal.compilerContext = arkts.Context.createFromString(source); pluginDriver.getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program); - const skipDeclCheck = buildConfig?.skipDeclCheck as boolean ?? true; - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, skipDeclCheck); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, arktsGlobal.compilerContext.peer, true); let ast = arkts.EtsScript.fromContext(); pluginDriver.getPluginContext().setArkTSAst(ast); pluginDriver.runPluginHook(PluginHook.PARSED); - arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, skipDeclCheck); + arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, arktsGlobal.compilerContext.peer, true); ast = arkts.EtsScript.fromContext(); pluginDriver.getPluginContext().setArkTSAst(ast); diff --git a/ets2panda/driver/build_system/src/init/process_build_config.ts b/ets2panda/driver/build_system/src/init/process_build_config.ts index 46727bff70..40285b662b 100644 --- a/ets2panda/driver/build_system/src/init/process_build_config.ts +++ b/ets2panda/driver/build_system/src/init/process_build_config.ts @@ -103,7 +103,7 @@ function initPlatformSpecificConfig(buildConfig: BuildConfig): void { buildConfig.dependencyAnalyzerPath = path.join(pandaSdkPath, 'bin', 'dependency_analyzer'); } - if (!buildConfig.enableDeclgenEts2Ts && !fs.existsSync(buildConfig.abcLinkerPath as string)) { + if (!fs.existsSync(buildConfig.abcLinkerPath as string)) { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_ARK_LINK_NOT_FOUND_FAIL, 'Ark_link not found in path.', @@ -113,7 +113,7 @@ function initPlatformSpecificConfig(buildConfig: BuildConfig): void { logger.printError(logData); } - if (!buildConfig.frameworkMode && !buildConfig.enableDeclgenEts2Ts && !fs.existsSync(buildConfig.dependencyAnalyzerPath as string)) { + if (!buildConfig.frameworkMode && !fs.existsSync(buildConfig.dependencyAnalyzerPath as string)) { const logData: LogData = LogDataFactory.newInstance( ErrorCode.BUILDSYSTEM_Dependency_Analyzer_NOT_FOUND_FAIL, 'Dependency_analyzer not found in path.', diff --git a/ets2panda/driver/build_system/src/types.ts b/ets2panda/driver/build_system/src/types.ts index b6012b37ce..d3012e4096 100644 --- a/ets2panda/driver/build_system/src/types.ts +++ b/ets2panda/driver/build_system/src/types.ts @@ -164,7 +164,6 @@ export interface DeclgenConfig { declgenV1OutPath?: string; declgenV2OutPath?: string; declgenBridgeCodePath?: string; - skipDeclCheck?: boolean; } export interface LoggerConfig { -- Gitee From ebf8806fbd199d8af0471c8566003daf3ba64114 Mon Sep 17 00:00:00 2001 From: kleene Date: Thu, 10 Jul 2025 12:41:51 +0800 Subject: [PATCH 081/107] change default compile mode Issue: ICKW7T Signed-off-by: kleene Change-Id: I0d67322465b27ef607307d7c7184c295a7cdbcdf --- ets2panda/driver/build_system/src/build/base_mode.ts | 5 +++-- ets2panda/driver/build_system/src/build/build_mode.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ets2panda/driver/build_system/src/build/base_mode.ts b/ets2panda/driver/build_system/src/build/base_mode.ts index 93a3e9b220..84435af40c 100644 --- a/ets2panda/driver/build_system/src/build/base_mode.ts +++ b/ets2panda/driver/build_system/src/build/base_mode.ts @@ -65,7 +65,8 @@ import { DependentModuleConfig, JobInfo, KPointer, - ModuleInfo + ModuleInfo, + ES2PANDA_MODE } from '../types'; import { ArkTSConfigGenerator } from './generate_arktsconfig'; import { SetupClusterOptions } from '../types'; @@ -141,7 +142,7 @@ export abstract class BaseMode { this.isBuildConfigModified = buildConfig.isBuildConfigModified as boolean | undefined; this.hasCleanWorker = false; this.byteCodeHar = buildConfig.byteCodeHar as boolean; - this.es2pandaMode = buildConfig?.es2pandaMode ?? 0; + this.es2pandaMode = buildConfig?.es2pandaMode ?? ES2PANDA_MODE.RUN; } public declgen(fileInfo: CompileFileInfo): void { diff --git a/ets2panda/driver/build_system/src/build/build_mode.ts b/ets2panda/driver/build_system/src/build/build_mode.ts index 0f14d3e8ba..ceb492b3e0 100644 --- a/ets2panda/driver/build_system/src/build/build_mode.ts +++ b/ets2panda/driver/build_system/src/build/build_mode.ts @@ -40,7 +40,7 @@ export class BuildMode extends BaseMode { await super.run(); } else { // Default fallback: Uses parallel execution (same as RUN_PARALLEL) - await super.runParallel(); + await super.run(); } } } \ No newline at end of file -- Gitee From 98dada9b3b109d34e791b58f4575106b559a8681 Mon Sep 17 00:00:00 2001 From: Lyupa Anastasia Date: Mon, 30 Jun 2025 18:19:20 +0300 Subject: [PATCH 082/107] Implement union type Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICIYJL Revert "Revert Union Type" This reverts commit 032615c5baa080fd5165fb07473288d487a0997b. UnionType checkcast/isinstance codegen; null type FE support implementing union class in runtime - Patch checkcast/isinstance codegen for Union types; - Emit unions with null as {...|null} instead of simple 'object' - Emit null type as std.core.Null Signed-off-by: Anna Antipina Signed-off-by: Lyupa Anastasia Signed-off-by: groshevmaksim Change-Id: I5b659865f3cbe9bb3dc411423bb8eb9c989ec8c1 --- ets2panda/checker/ETSchecker.cpp | 10 + ets2panda/checker/ETSchecker.h | 8 + ets2panda/checker/ets/function.cpp | 24 +- ets2panda/checker/ets/typeCheckingHelpers.cpp | 3 +- ets2panda/checker/ets/typeCreation.cpp | 8 +- ets2panda/checker/types/ets/etsUnionType.cpp | 140 +++++++---- ets2panda/checker/types/ets/etsUnionType.h | 16 +- ets2panda/compiler/core/ETSGen.cpp | 60 +++-- ets2panda/compiler/core/ETSGen.h | 10 +- ets2panda/compiler/core/ETSemitter.cpp | 8 +- ets2panda/compiler/scripts/signatures.yaml | 4 +- ets2panda/evaluate/debugInfoStorage.cpp | 2 +- ets2panda/scripts/arkui.properties | 2 +- ets2panda/test/unit/CMakeLists.txt | 4 + .../test/unit/any_ins_test/any_ins_test.cpp | 2 +- ets2panda/test/unit/union_emit_test.cpp | 238 ++++++++++++++++++ 16 files changed, 446 insertions(+), 93 deletions(-) create mode 100644 ets2panda/test/unit/union_emit_test.cpp diff --git a/ets2panda/checker/ETSchecker.cpp b/ets2panda/checker/ETSchecker.cpp index c301c826b3..d63dcd1f11 100644 --- a/ets2panda/checker/ETSchecker.cpp +++ b/ets2panda/checker/ETSchecker.cpp @@ -714,6 +714,16 @@ const GlobalArraySignatureMap &ETSChecker::GlobalArrayTypes() const return globalArraySignatures_; } +const ArenaSet &ETSChecker::UnionAssemblerTypes() const +{ + return unionAssemblerTypes_; +} + +ArenaSet &ETSChecker::UnionAssemblerTypes() +{ + return unionAssemblerTypes_; +} + Type *ETSChecker::GlobalTypeError() const { return GetGlobalTypesHolder()->GlobalTypeError(); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 2a61082efb..f621802d19 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -93,6 +93,7 @@ public: invokeToArrowSignatures_(Allocator()->Adapter()), arrowToFuncInterfaces_(Allocator()->Adapter()), globalArraySignatures_(Allocator()->Adapter()), + unionAssemblerTypes_(Allocator()->Adapter()), dynamicIntrinsics_ {DynamicCallIntrinsicsMap {Allocator()->Adapter()}, DynamicCallIntrinsicsMap {Allocator()->Adapter()}}, dynamicClasses_ {DynamicClassIntrinsicsMap(Allocator()->Adapter()), @@ -174,6 +175,9 @@ public: GlobalArraySignatureMap &GlobalArrayTypes(); const GlobalArraySignatureMap &GlobalArrayTypes() const; + const ArenaSet &UnionAssemblerTypes() const; + ArenaSet &UnionAssemblerTypes(); + Type *GlobalTypeError() const; [[nodiscard]] Type *InvalidateType(ir::Typed *node); [[nodiscard]] Type *TypeError(ir::Typed *node, const diagnostic::DiagnosticKind &diagKind, @@ -512,6 +516,8 @@ public: void SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType); + void CheckAmbiguousCall(Type *&mostSpecificType, Type *sigType, Signature *prevSig, Signature *sig, + const lexer::SourcePosition &pos); void CollectSuitableSignaturesForTypeInference(size_t paramIdx, ArenaVector &signatures, ArenaMultiMap &bestSignaturesForParameter, const ArenaVector &arguments); @@ -939,6 +945,7 @@ public: pendingConstraintCheckRecords_.clear(); constraintCheckScopesCount_ = 0; globalArraySignatures_.clear(); + unionAssemblerTypes_.clear(); GetCachedComputedAbstracts()->clear(); for (auto &dynamicCallIntrinsicsMap : dynamicIntrinsics_) { dynamicCallIntrinsicsMap.clear(); @@ -1098,6 +1105,7 @@ private: FunctionInterfaceMap arrowToFuncInterfaces_; size_t constraintCheckScopesCount_ {0}; GlobalArraySignatureMap globalArraySignatures_; + ArenaSet unionAssemblerTypes_; ComputedAbstracts *cachedComputedAbstracts_ {nullptr}; // NOTE(aleksisch): Extract dynamic from checker to separate class std::array dynamicIntrinsics_; diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index 5c22183d03..ba83f89e2a 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -1012,6 +1012,23 @@ static void InitMostSpecificType(TypeRelation *relation, const ArenaVectorIsETSObjectType() && mostSpecificType->IsETSObjectType()) || + (sigType->IsETSUnionType() && mostSpecificType->IsETSUnionType() && + ((Relation()->IsSupertypeOf(sigType->AsETSUnionType(), GlobalETSNullType()) && + Relation()->IsSupertypeOf(mostSpecificType->AsETSUnionType(), GlobalETSNullType())) || + // CC-OFFNXT(G.FMT.02-CPP) project code style + (Relation()->IsSupertypeOf(sigType->AsETSUnionType(), GlobalETSUndefinedType()) && + Relation()->IsSupertypeOf(mostSpecificType->AsETSUnionType(), GlobalETSUndefinedType()))))) && + !Relation()->IsAssignableTo(mostSpecificType, sigType) && + !Relation()->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { + auto funcName = sig->Function()->Id()->Name(); + LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); + } +} + void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature *&prevSig, std::tuple info, bool lookForClassType) @@ -1059,11 +1076,8 @@ void ETSChecker::SearchAmongMostSpecificTypes(Type *&mostSpecificType, Signature if (Relation()->IsAssignableTo(sigType, mostSpecificType)) { mostSpecificType = sigType; prevSig = sig; - } else if (sigType->IsETSObjectType() && mostSpecificType->IsETSObjectType() && - !Relation()->IsAssignableTo(mostSpecificType, sigType) && - !Relation()->IsLegalBoxedPrimitiveConversion(sigType, mostSpecificType)) { - auto funcName = sig->Function()->Id()->Name(); - LogError(diagnostic::AMBIGUOUS_CALL, {funcName, funcName, funcName, prevSig, funcName, sig}, pos); + } else { + CheckAmbiguousCall(mostSpecificType, sigType, prevSig, sig, pos); } } } diff --git a/ets2panda/checker/ets/typeCheckingHelpers.cpp b/ets2panda/checker/ets/typeCheckingHelpers.cpp index e000739bc0..90a5d7ca74 100644 --- a/ets2panda/checker/ets/typeCheckingHelpers.cpp +++ b/ets2panda/checker/ets/typeCheckingHelpers.cpp @@ -719,8 +719,7 @@ Type *ETSChecker::ResolveUnionUncheckedType(ArenaVector &&appar auto *unionType = CreateETSUnionType(std::move(apparentTypes)); ES2PANDA_ASSERT(unionType != nullptr); if (unionType->IsETSUnionType()) { - checker::Type *typeLUB = unionType->AsETSUnionType()->GetAssemblerLUB(); - return typeLUB; + return unionType->AsETSUnionType(); } // Is case of single apparent type, just return itself return unionType; diff --git a/ets2panda/checker/ets/typeCreation.cpp b/ets2panda/checker/ets/typeCreation.cpp index 0493a29be4..959fcad773 100644 --- a/ets2panda/checker/ets/typeCreation.cpp +++ b/ets2panda/checker/ets/typeCreation.cpp @@ -164,8 +164,12 @@ Type *ETSChecker::CreateETSUnionType(Span constituentTypes) if (newConstituentTypes.size() == 1) { return newConstituentTypes[0]; } - - return ProgramAllocator()->New(this, std::move(newConstituentTypes)); + auto *un = ProgramAllocator()->New(this, std::move(newConstituentTypes)); + auto ut = un->GetAssemblerType().Mutf8(); + if (std::count_if(ut.begin(), ut.end(), [](char c) { return c == ','; }) > 0) { + unionAssemblerTypes_.insert(un->GetAssemblerType()); + } + return un; } ETSTypeAliasType *ETSChecker::CreateETSTypeAliasType(util::StringView name, const ir::AstNode *declNode, diff --git a/ets2panda/checker/types/ets/etsUnionType.cpp b/ets2panda/checker/types/ets/etsUnionType.cpp index 6260a4ac8d..3bfeecc8cc 100644 --- a/ets2panda/checker/types/ets/etsUnionType.cpp +++ b/ets2panda/checker/types/ets/etsUnionType.cpp @@ -34,75 +34,125 @@ void ETSUnionType::ToString(std::stringstream &ss, bool precise) const void ETSUnionType::ToAssemblerType(std::stringstream &ss) const { - assemblerLub_->ToAssemblerTypeWithRank(ss); + ss << GetAssemblerType(); } void ETSUnionType::ToDebugInfoType(std::stringstream &ss) const { - assemblerLub_->ToDebugInfoType(ss); -} - -ETSUnionType::ETSUnionType(ETSChecker *checker, ArenaVector &&constituentTypes) - : Type(TypeFlag::ETS_UNION), constituentTypes_(std::move(constituentTypes)) -{ - ES2PANDA_ASSERT(constituentTypes_.size() > 1); - assemblerLub_ = ComputeAssemblerLUB(checker, this); + if (assemblerConstituentTypes_.size() == 1) { + assemblerConstituentTypes_[0]->ToDebugInfoType(ss); + return; + } + ss << "{U"; + // NOLINTNEXTLINE(modernize-loop-convert) + for (size_t idx = 0; idx < assemblerConstituentTypes_.size(); idx++) { + assemblerConstituentTypes_[idx]->ToDebugInfoType(ss); + if (idx != assemblerConstituentTypes_.size() - 1) { + ss << ","; + } + } + ss << "}"; } -bool ETSUnionType::EachTypeRelatedToSomeType(TypeRelation *relation, ETSUnionType *source, ETSUnionType *target) +static std::string GetAssemblerTypeString(Type *type) { - return std::all_of(source->constituentTypes_.begin(), source->constituentTypes_.end(), - [relation, target](auto *s) { return TypeRelatedToSomeType(relation, s, target); }); + std::stringstream ss; + type->ToAssemblerTypeWithRank(ss); + return ss.str(); } -bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, ETSUnionType *target) +void ETSUnionType::InitAssemblerTypeCache(ETSChecker *checker) { - return std::any_of(target->constituentTypes_.begin(), target->constituentTypes_.end(), - [relation, source](auto *t) { return relation->IsIdenticalTo(source, t); }); + ES2PANDA_ASSERT(!assemblerConstituentTypes_.empty()); + std::stringstream ss; + if (assemblerConstituentTypes_.size() == 1) { + assemblerConstituentTypes_[0]->ToAssemblerTypeWithRank(ss); + } else { + ss << "{U"; + for (size_t idx = 0; idx < assemblerConstituentTypes_.size(); idx++) { + if (idx != 0) { + ss << ","; + } + if (assemblerConstituentTypes_[idx]->IsETSNullType()) { + ss << compiler::Signatures::NULL_ASSEMBLY_TYPE; + continue; + } + assemblerConstituentTypes_[idx]->ToAssemblerTypeWithRank(ss); + } + ss << "}"; + } + assemblerTypeCache_ = util::UString(ss.str(), checker->ProgramAllocator()).View(); } -// This function computes effective runtime representation of union type -Type *ETSUnionType::ComputeAssemblerLUB(ETSChecker *checker, ETSUnionType *un) +void ETSUnionType::CanonicalizedAssemblerType(ETSChecker *checker) { - auto *const apparent = checker->GetApparentType(un); - ES2PANDA_ASSERT(apparent != nullptr); + auto *const apparent = checker->GetApparentType(this); if (!apparent->IsETSUnionType()) { - return apparent; + assemblerConstituentTypes_.push_back(apparent); + return; } - if (apparent != un) { - return apparent->AsETSUnionType()->assemblerLub_; + if (apparent != this) { + const auto &types = apparent->AsETSUnionType()->GetAssemblerTypes(); + assemblerConstituentTypes_.insert(assemblerConstituentTypes_.begin(), types.begin(), types.end()); + return; } - un = apparent->AsETSUnionType(); - - Type *lub = nullptr; - for (auto *t : un->ConstituentTypes()) { - if (t->IsTypeError()) { - return checker->GlobalTypeError(); - } - // NOTE(vpukhov): #19701 void refactoring - ES2PANDA_ASSERT(t->IsETSReferenceType() || t->IsETSVoidType()); - t = t->IsETSVoidType() ? checker->GlobalETSUndefinedType() : t; - if (lub == nullptr || lub->IsETSUndefinedType()) { - lub = t; + ES2PANDA_ASSERT(constituentTypes_.size() > 1); + bool hasNull = false; + for (auto *type : constituentTypes_) { + ES2PANDA_ASSERT(!type->IsETSUnionType()); + if (type->IsETSUndefinedType() || type->IsETSVoidType()) { continue; } - if (lub == t || t->IsETSUndefinedType()) { + if (type->IsETSNullType() && !hasNull) { + hasNull = true; + assemblerConstituentTypes_.push_back(type); continue; } - if (t->IsETSNullType()) { - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); + if (type->IsTypeError()) { + assemblerConstituentTypes_.clear(); + assemblerConstituentTypes_.push_back(checker->GlobalTypeError()); + return; } - if (t->IsETSObjectType() && lub->IsETSObjectType()) { - lub = checker->GetClosestCommonAncestor(lub->AsETSObjectType(), t->AsETSObjectType()); - } else if (t->IsETSArrayType() && lub->IsETSArrayType()) { - // NOTE: can compute "common(lub, t)[]" - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); - } else { - return checker->GetGlobalTypesHolder()->GlobalETSObjectType(); + auto found = + std::find_if(assemblerConstituentTypes_.begin(), assemblerConstituentTypes_.end(), + [&type](Type *t) { return GetAssemblerTypeString(type) == GetAssemblerTypeString(t); }); + if (found == assemblerConstituentTypes_.end()) { + assemblerConstituentTypes_.push_back(type); } } - return checker->GetNonConstantType(lub); + if (assemblerConstituentTypes_.empty()) { + assemblerConstituentTypes_.push_back(checker->GlobalETSObjectType()); + return; + } + if (assemblerConstituentTypes_.size() == 1) { + return; + } + + std::sort(assemblerConstituentTypes_.begin(), assemblerConstituentTypes_.end(), + [](Type *a, Type *b) { return GetAssemblerTypeString(a) < GetAssemblerTypeString(b); }); +} + +ETSUnionType::ETSUnionType(ETSChecker *checker, ArenaVector &&constituentTypes) + : Type(TypeFlag::ETS_UNION), + constituentTypes_(std::move(constituentTypes)), + assemblerConstituentTypes_(checker->ProgramAllocator()->Adapter()) +{ + ES2PANDA_ASSERT(constituentTypes_.size() > 1); + CanonicalizedAssemblerType(checker); + InitAssemblerTypeCache(checker); +} + +bool ETSUnionType::EachTypeRelatedToSomeType(TypeRelation *relation, ETSUnionType *source, ETSUnionType *target) +{ + return std::all_of(source->constituentTypes_.begin(), source->constituentTypes_.end(), + [relation, target](auto *s) { return TypeRelatedToSomeType(relation, s, target); }); +} + +bool ETSUnionType::TypeRelatedToSomeType(TypeRelation *relation, Type *source, ETSUnionType *target) +{ + return std::any_of(target->constituentTypes_.begin(), target->constituentTypes_.end(), + [relation, source](auto *t) { return relation->IsIdenticalTo(source, t); }); } void ETSUnionType::Identical(TypeRelation *relation, Type *other) diff --git a/ets2panda/checker/types/ets/etsUnionType.h b/ets2panda/checker/types/ets/etsUnionType.h index 54c15370d8..71c9ac8601 100644 --- a/ets2panda/checker/types/ets/etsUnionType.h +++ b/ets2panda/checker/types/ets/etsUnionType.h @@ -54,10 +54,9 @@ public: [[nodiscard]] ArenaVector GetNonConstantTypes(ETSChecker *checker) const noexcept; - // Do not use it anywhere except codegen - Type *GetAssemblerLUB() const noexcept + const util::StringView &GetAssemblerType() const { - return assemblerLub_; + return assemblerTypeCache_; } template @@ -105,10 +104,17 @@ private: checker::ETSChecker *checker, checker::ETSObjectType *sourceType, std::map &numericTypes) const noexcept; - static Type *ComputeAssemblerLUB(ETSChecker *checker, ETSUnionType *un); + void CanonicalizedAssemblerType(ETSChecker *checker); + void InitAssemblerTypeCache(ETSChecker *checker); + + const ArenaVector &GetAssemblerTypes() const + { + return assemblerConstituentTypes_; + } ArenaVector const constituentTypes_; - Type *assemblerLub_ {nullptr}; + ArenaVector assemblerConstituentTypes_; + util::StringView assemblerTypeCache_; }; } // namespace ark::es2panda::checker diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 64969cbd23..ff54d72f97 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -591,17 +591,19 @@ void ETSGen::ReturnAcc(const ir::AstNode *node) } } -static bool IsNullUnsafeObjectType(checker::Type const *type) +bool ETSGen::IsNullUnsafeObjectType(checker::Type const *type) const { ES2PANDA_ASSERT(type != nullptr); - return type->IsETSObjectType() && type->AsETSObjectType()->IsGlobalETSObjectType(); + auto const checker = const_cast(Checker()); + return checker->Relation()->IsSupertypeOf(checker->GetApparentType(type), checker->GlobalETSObjectType()); } // Implemented on top of the runtime type system, do not relax checks, do not introduce new types -void ETSGen::TestIsInstanceConstituent(const ir::AstNode *const node, std::tuple